스크립트에서 awk를 실행할 때 오류가 발생했습니다.

스크립트에서 awk를 실행할 때 오류가 발생했습니다.

some.txt 파일이 있습니다

-rwxrw-r-- 1 ivamshky ivamshky    152 Apr  2 00:42 12.sh~
-rw-rw-r-- 1 ivamshky ivamshky     58 Apr  6 19:03 a.c
-rw-rw-r-- 1 ivamshky ivamshky     98 Apr  1 20:27 all.sh
-rwxrwxr-x 1 ivamshky ivamshky   8509 Apr  6 19:04 a.out
-rw-rw-r-- 1 ivamshky ivamshky     46 Apr  6 19:07 a.py
-rw-rw-r-- 1 ivamshky ivamshky    399 Apr 18 00:37 attendance.csv
-rw-rw-r-- 1 ivamshky ivamshky    341 Apr 20 01:08 attendance.sh
-rw-rw-r-- 1 ivamshky ivamshky      0 Apr 19 16:21 awk
-rw-rw-r-- 1 ivamshky ivamshky    212 Apr 20 01:41 awktest.sh

이제 현재 디렉터리의 파일 이름이 위 파일에 존재하는 경우 "FOUND"를 사용하여 해당 행에 새 열을 추가하고 싶습니다. 예: awktest.sh가 pwd에 존재하는 경우. 그러면 출력은 다음과 같습니다.

-rw-rw-r-- 1 ivamshky ivamshky    212 Apr 20 01:41 awktest.sh   FOUND

제가 이 스크립트를 작성했습니다. (도움을 받아 감사합니다.)

 #!/bin/bash
for fn in *
do
    n=$( awk -v fn="$fn" '$0 ~ fn { print NR }' some.txt )
    awk -v n="$n" 'NR==n { $(NF+1)="Found" }1' some.txt >some.out
done

그러나 출력 파일에는 새 열이 추가되지 않습니다. (some.txt에 존재하는 pwd 파일이 일부 있습니다.)

답변1

코드가 매우 복잡합니다. 예를 들어

>>  list=$(ls -l | awk 'NR > 1 { print $9;}')
>>  for fn in $list 

왜 이 작업을 수행 ls -l한 다음 $9(파일 이름 - 그러나 이는 파일 이름에 공백이 없는 경우에만 작동하는지)를 추출해야 합니다.

for fn in *

그런 다음 grep줄 번호 및 필드 추출에 대한 awk몇 가지 작업을 수행합니다.

>>  n=`grep -n "$fn" some.txt | awk -F":" '{ print $1;}'`

awk하지만 단순히 일치하도록 놔두는 것은 어떨까요?

n=$( awk -v fn="$fn" '$0 ~ fn { print NR }' some.txt )

마지막으로 인용문을 사용하여 쉘과 awk 사이를 앞뒤로 전환하지 마십시오.

>>  awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out

변수를 다음과 같은 인수로 깔끔하게 전달합니다.

awk -v n="$n" 'NR==n { $(NF+1)="Found" } 1'


이제 다음 부분을 하나로 합치십시오.

for fn in *
do
    n=$( awk -v fn="$fn" '$0 ~ fn { print NR }' some.txt )
    awk -v n="$n" 'NR==n { $(NF+1)="Found" } 1' some.txt >some.out
    mv some.out some.txt
done

이것이 정확히 원하는 것인지는 확실하지 않지만 코드가 더 깨끗하고 최소한 문제가 더 적습니다. 이제 이번 개편으로 이 모든 것을 한 번에 처리
할 수 있을 것 같습니다 . awk(그러나 나는 그것을 독자들의 연습문제로 남겨둔다.)

답변2

쉽게 할 수 있다sed

#!/bin/bash
unset pattern
for fn in *
do
    pattern=${pattern:+${pattern}\\|}$f
done
sed -i "/$pattern/s/$/ Found/" some.txt

답변3

!/bin/bash
list=$(ls -l | awk 'NR > 1 { print $9;}')
for fn in list 
do
echo $fn
    n=`grep -n "$fn" some.txt | awk -F":" '{ print $1;}'` # change this
    awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out
    mv some.out some.txt
done



!/bin/bash
list=$(ls -l | awk 'NR > 1 { print $9;}')
for fn in list; do # also decided to clean this up
    echo $fn
    n=$(grep -n "$fn" some.txt | awk -F":" '{ print $1;}') # to this
    awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out # also, what is this line supposed to do? There is usually a better way to do something that have to run a mv command to overwrite
    mv some.out some.txt
done

다른 일이 있을 수도 있지만 아직 커피를 마시지 않았습니다.

http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html

답변4

스크립트 문제:

  • SC2006- 전통적인 `..` 대신 $(..)를 사용하세요.
  • SC2012- 영숫자가 아닌 파일 이름을 더 잘 처리하려면 ls 대신 find를 사용하십시오.
  • SC1035- ! 뒤에 필수 공백이 없습니다.

    1  !/bin/bash
        ^––SC1035 You are missing a required space after the !.
    2  list=$(ls -l | awk 'NR > 1 { print $9;}')
              ^––SC2012 Use find instead of ls to better handle non-alphanumeric filenames.
    3  for fn in $list 
    4  do
    5  
    6      n=`grep -n "$fn" some.txt | awk -F":" '{ print $1;}'`
             ^––SC2006 Use $(..) instead of legacy `..`.
    7      awk -F" " 'NR=='"$n"'{OFS=" "; $(NF+1)="Found";}1' some.txt>some.out
    8      mv some.out some.txt
    9  done
    

원천

관련 정보