awk 또는 sed를 사용하여 csv 파일의 각 줄 끝에 wc -l 출력을 추가하는 방법

awk 또는 sed를 사용하여 csv 파일의 각 줄 끝에 wc -l 출력을 추가하는 방법

wc -l파일의 각 줄 끝에 출력을 추가 하려고 합니다 . 한 파일에 20개의 레코드/라인이 있으면 해당 파일의 각 라인 끝에 숫자 20을 추가하고 다음 파일에 100개의 레코드/라인이 있으면 각 라인 끝에 100을 추가하고 싶습니다. 다음 명령을 시도했지만 원하는 대로 수행되지 않았습니다.

awk -v char=$(wc -l FILENAME | cut -f1 -d' ') '{print $0"," char}' FILENAME

답변1

이것은 이상한 요청이지만 원하는 대로 작동할 것입니다.

#!/bin/bash

shopt -s nullglob

for f in *.csv; do
   size="$(wc -l <$f)"
   sed -i "s/$/,$size/g" "$f"
done

exit

이렇게 하면 .csv현재 디렉터리의 모든 파일이 내부에서 편집됩니다.

편집: Mac에서는 백업 확장이 필요할 수 있으므로 sed명령이 필요할 수 있습니다 . sed -i '.bak' "s/$/, $size/g" "$f"그러나 이것은 내 Linux 시스템에서는 작동하지 않습니다.

답변2

순수한 awk 솔루션:

awk '
  # Read the file and print it with the additional column
  function process_file( SIZE, FILE,    NEW_FILE ) {
    NEW_FILE = FILE ".tmp"
    while ( ( getline < FILE ) > 0 ){
      print $0 "," SIZE > NEW_FILE
    }
    close( FILE )
    close( NEW_FILE )
    system( "mv -f " NEW_FILE " " FILE )
  }

  # File name has changed, we just passed the end of a file,
  # => print the current file
  ( NR > 1 ) && ( PREV_FILE != FILENAME ) {
    process_file( OLD_FNR, PREV_FILE )
  }

  {
    # Save the current file name and line number within the file
    PREV_FILE = FILENAME
    OLD_FNR = FNR
  }

  END {
    # Print the last file, if any
    if ( PREV_FILE != "" ) {
      process_file( OLD_FNR, PREV_FILE )
    }
  }' file1 file2 ...

이것은 더 쉽습니다멍하니, 그것 중 하나파일 끝건강 상태:

gawk '
  # Read the file and print it with the additional column
  function process_file( SIZE, FILE,    NEW_FILE ){
    NEW_FILE = FILE ".tmp"
    while ( ( getline < FILE ) > 0 ){
      print $0 "," SIZE > NEW_FILE
    }
    close( FILE )
    close( NEW_FILE )
    system( "mv -f " NEW_FILE " " FILE )
  }
  # End of a file, print the file
  # FILENAME is the name of the current file being read
  # FNR is the line number within the file
  ENDFILE {
    process_file( FNR, FILENAME )
  }' file1 file2 ...

답변3

그것은 awk가 아니지만 간단하게 작동합니다.

number=$(wc -l $1 | cut -d ' ' -f 1)
sed -i "s/\$/ ${number}/" $1

또는 한 줄에 입력하려는 경우:

sed -i "s/\$/ $(wc -l $file | cut -d ' ' -f 1)/" $file

예:

user@server 22:59:58:/tmp$ file='FILENAME'
user@server 23:00:07:/tmp$ for ((i=0; i < 10; i++)) ; do echo 123 >> "$file"; done
user@server 23:00:18:/tmp$ cat "$file"
123
123
123
123
123
123
123
123
123
123
user@server 23:00:25:/tmp$ wc -l "$file"
10 FILENAME
user@server 23:00:30:/tmp$ sed -i "s/\$/ $(wc -l "$file" | cut -d ' ' -f 1)/" "$file"
user@server 23:00:37:/tmp$ cat "$file"
123 10
123 10
123 10
123 10
123 10
123 10
123 10
123 10
123 10
123 10
user@server 23:00:39:/tmp$
user@server 23:01:54:/tmp$ ls -lA "$file"
-rw-r--r-- 1 user user 70 Dez  4 23:00 FILENAME

관련 정보