여러 텍스트 파일에 동일한 sed 명령 적용

여러 텍스트 파일에 동일한 sed 명령 적용

파일에 대한 전처리를 수행하고 있습니다. 다음 형식의 데이터가 포함된 텍스트 파일이 2개 있습니다.

텍스트 파일 1

"Name","Age","Class"
"Total Students:","247"
"John","14","8"
"Sara","13","8"

텍스트 파일 2

"Name","Age","Class"
"Total Students:","119"
"John","15","9"
"Sara","16","9"

내가 원하는 것은 이 파일과 따옴표에서 처음 두 줄을 제거한 후 다음 명령을 사용하여 파일을 출력 디렉터리로 이동하는 것입니다.

sed '1d' "$file" >> temp.txt
sed -i '1d' temp.txt
sed -i 's/"//g' temp.txt

mv temp.txt output/$file

내가 직면한 문제는 이러한 명령이 단일 파일에서만 작동한다는 것입니다. 파일 이름은class_8.txt그리고class_9.txt. 두 파일에 동일한 명령을 적용하는 솔루션이 있습니까? 원본 파일은 유지하고 처리된 파일을 출력 폴더로 이동하고 싶습니다.

답변1

sed여러 파일에서 편리하게 실행하고 동시에 여러 파일에 쓰도록 할 수는 없습니다 (입력과 출력이 별도의 파일이어야 하는 경우). 비표준 확장자를 사용하거나 표현식에 출력 파일 이름을 하드코딩하여 사용할 수 있습니다 sed.

tail작업은 매우 간단하지만 루프에서 and 를 사용하고 싶을 수도 있습니다 .tr

for file in Class_{8,9}.txt; do
    tail -n +3 "$file" | tr -d '"' >output/"$file"
done

아니면 정말로 sed사용 하고 싶다면

for file in Class_{8,9}.txt; do
    sed -e '1,2d' -e 's/"//g' "$file" >output/"$file"
done

파일을 먼저 복사한 다음 sed복사본에 대해 한 번에 내부 편집을 실행할 수도 있습니다. 어떤 의미에서 이것은 루프를 GNU의 내부 작업에 위임합니다 sed.

cp Class_{8,9}.txt output
sed -i -e '1,2d' -e 's/"//g' output/Class_{8,9}.txt

필드에 쉼표나 줄 바꿈이 포함된 경우 큰따옴표를 제거하면 잘못된 CSV 출력을 작성하게 됩니다. 원하지 않는 큰따옴표만 제거하려면 csvformat다음 과 같은 CSV 파서를 사용하세요.csvkit.

위의 명령은 모두 이 output디렉터리가 파일을 생성할 수 있는 기존 디렉터리라고 가정합니다.

답변2

동일한 명령으로 다른 파일에 쓰려면 명령을 사용하거나 명령에 대한 플래그를 sed사용할 수 있습니다 .wws

귀하의 경우 줄의 마지막 필드는 어떤 파일에 써야 하는지 결정하는 클래스 필드인 것 같으므로 어느 것이 소스 파일인지 전혀 신경 쓸 필요가 없습니다. 처음 두 줄은 유효한 클래스가 없기 때문에 무시할 수 있으므로 신경 쓸 필요조차 없습니다.

sed -ne 's/"//g;/,8$/woutput/Class_8.txt' -e '/,9$/woutput/Class_9.txt' file*

따라서 모든 행에 대해 큰따옴표를 제거한 s/"//g다음 작성 해야 하는 마지막 필드의 모든 행을 /,8$/선택합니다 . 9레벨도 마찬가지다. 이 옵션은 기본 출력을 억제합니다 .8woutput/Class_8.txt-n

물론 이는 많은 수의 파일에 대해서는 확장 가능하지 않습니다.

답변3

-i.sufsed이전 파일 에 추가 .suf하고 변경 사항을 새 파일에 씁니다. 따라서 1) sed파일을 수정하고 이전 파일의 접미사를 유지하고, 2) 새 파일을 이동하고, 3) 접미사를 제거하여 이전 파일의 이름을 원래 이름으로 바꿀 수 있습니다.

sed -i.bup '1,2d;s/"//g' file1.txt file2.txt file3.txt
mv file{1..3}.txt output
rename 's/.bup$//' file{1..3}.txt.bup

( rename때때로 호출되거나 prename배포판 perl-rename에 따라 다름)

답변4

이는 두 파일을 모두 편집하고 output파일 이름은 동일하지만 편집된 버전을 가진 디렉터리 로 출력을 리디렉션하려는 경우에 awk작동할 수 있습니다 .

$ awk 'FNR > 1 { gsub(/\"/,""); print > "output/"FILENAME ; next } FNR > 1 { gsub(/\"/,""); print > "output/"FILENAME }' Class_8.txt Class_9.txt

아니면 스크립트로

$ cat awk.script

FNR > 1 {                      #Remove line 1 from first file
    gsub(/\"/,"")              #Substitute all double quotes for nothing
    print > "output/"FILENAME  #Send the output to new directory with the same filename
    next                       #Move on to the next file
} FNR > 1 {                    #Remove line 1 from second file
    gsub(/\"/,"")              #Substitute all double quotes for nothing
    print > "output/"FILENAME  #Send the output to new directory with the same filename
}

파일과 함께 스크립트를 사용하려면 다음 명령을 실행할 수 있습니다.

$ awk -f awk.script Class_8.txt Class_9.txt

출력은 다음과 같습니다

$ cat output/Class_8.txt
Total Students:,247
John,14,8
Sara,13,8
$ cat output/Class_9.txt
Total Students:,119
John,15,9
Sara,16,9

관련 정보