비순환적

비순환적

나는 다음 스크립트를 작성했습니다.

#!/bin/bash

#files list
file1=/tmp/1wall_long.txt
file2=/tmp/1wall_test1.txt
file3=/tmp/1wall_test2.txt
file4=/tmp/1wall_test3.txt
file5=/tmp/3mt_long.txt
file6=/tmp/3mt_OpenSpace_test1.txt
file7=/tmp/3mt_OpenSpace_test2.txt
file8=/tmp/3mt_OpenSpace_test3.txt
file9=/tmp/3rooms_test1.txt
file10=/tmp/3rooms_test2.txt
file11=/tmp/3rooms_test3.txt
file12=/tmp/20mt_OpenSpace_test1.txt
file13=/tmp/20mt_OpenSpace_test2.txt
file14=/tmp/20mt_OpenSpace_test3.txt

#script for 1wall_long file
if [ ! -e "$file1" ]; then #check if the file exist
    echo "File 1wall_long.txt does not exist" #if not exist print echo output
else
    sed -i -e 's/- /-/g' $file1 #remove space on the first 10 values
    awk '{print $7}' $file1 > /tmp/1wall_long_S.txt #print the column number 7 and copy the output in a file
    rm $file1 #remove old file
fi

변수에 설명된 모든 파일에 대해 스크립트 반복(기본적으로 다른 변수를 사용하여 동일한 스크립트를 14번 반복했습니다.) 이를 수행하는 더 좋은 방법이 있으며 이러한 경우 모범 사례는 무엇입니까?

답변1

비순환적

먼저 함수를 사용해 보세요

function sevenc
{


if [ ! -e "$1" ]; then #check if the file exist
    echo "File $1 does not exist" #if not exist print echo output
else
    sed -i -e 's/- /-/g' "$1" #remove space on the first 10 values
    awk '{print $7}' "$1" > /tmp/$(basename $1.txt)_S.txt #print the column number 7 and copy the output in a file
    rm "$1"  #remove old file
fi
}
  • 쉘이 함수를 인식하면 인수(있는 경우 $1 $2... 등)를 전달합니다.
  • 덧붙여서

's/- /-/g' "$1" #처음 10개 값에서 공백 제거

아니요, 1, 4, 10, 255 등 모두 space-한 줄로 이동합니다 .-

그러면 더 이상 vars가 필요하지 않습니다.

sevenc /tmp/1wall_long.txt
sevenc /tmp/1wall_test1.txt
sevenc /tmp/1wall_test2.txt
sevenc /tmp/1wall_test3.txt
sevenc /tmp/3mt_long.txt
sevenc /tmp/3mt_OpenSpace_test1.txt
sevenc /tmp/3mt_OpenSpace_test2.txt
sevenc /tmp/3mt_OpenSpace_test3.txt
sevenc /tmp/3rooms_test1.txt
sevenc /tmp/3rooms_test2.txt
sevenc /tmp/3rooms_test3.txt
sevenc /tmp/20mt_OpenSpace_test1.txt
sevenc /tmp/20mt_OpenSpace_test2.txt
sevenc /tmp/20mt_OpenSpace_test3.txt

(더 이상 fileXX var를 사용하지 않는 경우)

루프 없음(해결책 2)

더 많은 매개변수를 전달하고 Terdon의 최적화를 사용하려면 다음을 시도하십시오.

function eight
{

file=$1
destdir=${2-/tmp} # use second arg if defined, else /tmp
exten=${3-S} 

if [ ! -e "$file" ]; then #check if the file exist
    echo "File $file does not exist" #if not exist print echo output
else
    sed  -e 's/- /-/g' "$file" \
    awk '{print $7}' "$1" > /"$destdir"/$(basename $1.txt)_"$exten".txt #print the column number 7 and copy the output in a file
    rm "$file"  #remove old file
fi
}

으로 호출됩니다

eight /tmp/1wall_test3.txt /my/projec/dir T ## will use /my/project/dir as dit, T as extension
eight /tmp/1wall_test1.txt /my/project ## will use /my/project as dir
eignt /tmp/1wall_test2.txt ## will use default value

이러한 함수는 .bashrc에 정의되어 대화형으로 사용할 수 있습니다.

루프 포함

while read f
do
if [ ! -e "$f" ]; then #check if the file exist
    echo "File $1 does not exist" #if not exist print echo output
else
    sed -i -e 's/- /-/g' "$f" #remove space on the first 10 values
    awk '{print $7}' "$f" > "/tmp/$(basename $f .txt)_S.txt" #print the column number 7 and copy the output in a file
    rm "$f"  #remove old file
fi
done <<EOF
/tmp/1wall_long.txt
/tmp/1wall_test1.txt
/tmp/1wall_test2.txt
/tmp/1wall_test3.txt
/tmp/3mt_long.txt
/tmp/3mt_OpenSpace_test1.txt
/tmp/3mt_OpenSpace_test2.txt
/tmp/3mt_OpenSpace_test3.txt
/tmp/3rooms_test1.txt
/tmp/3rooms_test2.txt
/tmp/3rooms_test3.txt
/tmp/20mt_OpenSpace_test1.txt
/tmp/20mt_OpenSpace_test2.txt
/tmp/20mt_OpenSpace_test3.txt
EOF

답변2

개인적으로 나는 파일 이름을 하드코딩하는 것을 피하고 싶습니다. 이는 좋은 생각이 아니며 일반적으로 대상 파일을 매개변수로 전달하는 것이 더 좋습니다. 또한 파일을 내부에서 수정한 다음 원본 파일을 삭제합니다. 이는 그다지 효율적이지 않습니다. 파일을 동적으로 수정하고 디스크에 쓰지 않고 일곱 번째 열을 인쇄하기만 하면 됩니다. 예를 들어:

#!/usr/bin/env bash

## Iterate over the file names given
for file in "$@"; do
    ## Get the output file's name. The ${file%.*} is
    ## the file's anme without its extension.
    outfile="${file%.*}"_S.txt
    ## If the file exists
    if [ -e "$file" ]; then
    ## remove the spaces and print the 7th column
    sed 's/- /-/g' "$file" | awk '{print $7}' > "$outfile" &&
        ## Delete the original but only if the step
        ## above was successful (that's what the && does)/
        rm "$file" 
    else
    ## If the file doesn't exist, print an error message
    echo "The file $file does not exist!"
    fi
done

그런 다음 다음과 같이 스크립트를 실행할 수 있습니다.

foo.sh /tmp/1wall_long.txt /tmp/1wall_test1.txt /tmp/1wall_test2.txt /tmp/1wall_test3.txt /tmp/20mt_OpenSpace_test1.txt /tmp/20mt_OpenSpace_test2.txt /tmp/20mt_OpenSpace_test3.txt /tmp/3mt_long.txt /tmp/3mt_OpenSpace_test1.txt /tmp/3mt_OpenSpace_test2.txt /tmp/3mt_OpenSpace_test3.txt /tmp/3rooms_test1.txt /tmp/3rooms_test2.txt /tmp/3rooms_test3.txt 

이름을 하드코딩하려면 @choroba가 제안한 대로 배열을 사용하세요.

#!/usr/bin/env bash

files=(/tmp/1wall_long.txt /tmp/1wall_test1.txt /tmp/1wall_test2.txt /tmp/1wall_test3.txt /tmp/20mt_OpenSpace_test1.txt /tmp/20mt_OpenSpace_test2.txt /tmp/20mt_OpenSpace_test3.txt /tmp/3mt_long.txt /tmp/3mt_OpenSpace_test1.txt /tmp/3mt_OpenSpace_test2.txt /tmp/3mt_OpenSpace_test3.txt /tmp/3rooms_test1.txt /tmp/3rooms_test2.txt /tmp/3rooms_test3.txt )


## Iterate over the file names given
for file in "${files[@]}"; do
    ## Get the output file's name. The ${file%.*} is
    ## the file's anme without its extension.
    outfile="${file%.*}"_S.txt
    ## If the file exists
    if [ -e "$file" ]; then
    ## remove the spaces and print the 7th column
    sed 's/- /-/g' "$file" | awk '{print $7}' > "$outfile" &&
        ## Delete the original but only if the step
        ## above was successful (that's what the && does)/
        rm "$file" 
    else
    ## If the file doesn't exist, print an error message
    echo "The file $file does not exist!"
    fi
done

답변3

다음을 사용하여 파일 배열을 사용하고 반복할 수 있습니다 for.

#!/bin/bash

files=(/tmp/1wall_long.txt
       /tmp/1wall_test1.txt
       /tmp/1wall_test2.txt
       /tmp/1wall_test3.txt
       /tmp/3mt_long.txt
       /tmp/3mt_OpenSpace_test1.txt
       /tmp/3mt_OpenSpace_test2.txt
       /tmp/3mt_OpenSpace_test3.txt
       /tmp/3rooms_test1.txt
       /tmp/3rooms_test2.txt
       /tmp/3rooms_test3.txt
       /tmp/20mt_OpenSpace_test1.txt
       /tmp/20mt_OpenSpace_test2.txt
       /tmp/20mt_OpenSpace_test3.txt )

for file in "${files[@]}" ; do
    if [ ! -e "$file" ]; then
        echo "File $file does not exist"
    else
        sed -i -e 's/- /-/g' "$file"
        # Use parameter expansion to create the new file name.
        newfile=${file%.txt}_S.txt
        awk '{print $7}' "$file" > "$newfile"
        rm "$file"
    fi
done

관련 정보