동일한 확장명(예: .txt)을 가진 파일이 여러 개 있고 이를 연결하고 싶습니다. 사용 중이지만 cat *.txt > concat.txt
concat.txt에서 각 파일을 구별하기 위해 각 파일 사이에 새 줄을 추가하고 싶습니다.
다음과 같은 구현 대신 단일 bash 명령을 사용하여 이를 수행할 수 있습니까?이것?
감사해요
답변1
명령이 아니라 간단한 한 줄입니다.
for f in *.txt; do cat -- "$f"; printf "\n"; done > newfile.txt
이 오류가 발생합니다.
cat: newfile.txt: input file is output file
그러나 적어도 GNU/Linux 시스템에서는 이를 무시할 수 있습니다. Stéphane Chazelas는 주석에서 분명히 다른 시스템에서는 이것이 무한 루프를 일으킬 수 있다고 지적했습니다. 따라서 이를 피하려면 다음을 시도해 보십시오.
for f in *.txt; do
[[ "$f" = newfile.txt ]] || { cat -- "$f"; printf "\n"; }
done > newfile.txt
.txt
또는 루프에 포함되지 않도록 출력 파일에 확장자를 추가 하지 마십시오 (어쨌든 필요하지 않으며 전혀 차이가 없습니다).
for f in *.txt; do cat -- "$f"; printf "\n"; done > newfile
답변2
GNU 사용 sed
:
sed -s -e $'$a\\\n' ./*.txt >concat.out
concat.out
이렇게 하면 처리된 각 파일의 끝에 빈 줄을 추가하면서 모든 데이터를 연결합니다 .
-s
sed
주소를 $
마지막 줄과 일치시키는 GNU 옵션각평소처럼 모든 데이터의 마지막 줄 대신 파일. 이 a
명령은 주어진 위치에 하나 이상의 줄을 추가합니다. 추가된 데이터는 개행 문자입니다. 개행 문자는 "C 문자열"로 인코딩됩니다 $'\n'
. 이는 우리가 사용하는 셸이 이를 이해한다는 의미입니다(예: bash
또는 zsh
). 그렇지 않으면 리터럴 줄 바꿈으로 추가해야 합니다.
sed -s -e '$a\
' ./*.txt >concat.out
실제로 '$a\\'
그것도 효과가 있는 것 같지만 '$a\ '
왜 그런지는 잘 모르겠습니다.
누군가가 이 a
명령을 올바르게 실행하기에는 너무 번거롭다고 생각하는 경우에도 작동합니다.
sed -s -e '${p;g;}' ./*.txt >concat.out
이러한 변형 중 하나는 마지막 파일의 출력 끝에 빈 줄도 삽입합니다. 마지막 줄 바꿈이 필요하지 않은 경우 sed '$d'
출력 파일로 리디렉션하기 전에 전체 결과를 전달하여 제거합니다.
sed -s -e '${p;g;}' ./*.txt | sed -e '$d' >concat.out
답변3
GNU 사용 awk
:
gawk -v RS='^$' -v ORS= '{
print sep $0; sep="\n";
}' ./file*.txt >single.file
바라보다awk의 후루룩 모드?
파일 이름의 접두사 점 슬래시는 이와 같은 ./
이름의 파일을 읽는 데 file=x.txt
문제가 발생하는 것을 방지하는 데 사용됩니다.awk
끈로서바꾸다awk
코드 뒤에 나타나는 경우 ;
또 다른 GNU awk
접근 방식은 다음과 같습니다.
gawk 'BEGINFILE{if (ARGIND>1) print ""};1' ./file*.txt >single.txt
마지막 줄이 개행으로 끝나지 않더라도 빈 줄을 추가하고 전체 파일을 메모리에 로드하지 않기 때문에 이것이 더 좋습니다.
대안이 있지만 마지막 줄줄이를 sed
제거하려면 다른 파이프를 추가하여 제거해야 합니다.\n
sed ... |
sed -s '$s/$/\n/' file*.txt >single.file
답변4
zsh
P
glob에 의해 생성된 각 파일 이름 앞에 인수를 붙이는 데 사용되는 glob 한정자가 있습니다 .
일반적으로 각 파일 이름 앞에 주어진 옵션을 붙이는 데 사용되지만 cmd *.txt(P[-i])
여기서는 각 파일 앞에 주어진 파일을 삽입하는 데 사용할 수 있습니다. 빈 줄이 포함된 임시 파일은 를 사용하여 완성할 수 있으므로 =(print)
다음을 수행할 수 있습니다.
() { cat file*.txt(P[$1]); } =(print)
Linux 또는 Cygwin에서는 다음을 수행할 수도 있습니다.
cat file*.txt(P[/dev/stdin]) <<< ''
비어 있지 않은 파일 사이에만 빈 줄을 추가합니다.
awk 'NR > 1 && FNR == 1 {print ""}; {print}' ./file*.txt