명령을 사용하여 파일을 연결하는 데 이상한 문제가 있습니다 cat
. 각각 문자열이 포함된 두 개의 파일이 있습니다.
파일 1:
ABC
파일 2:
DEF
내가 그렇든가 cat file1 file2
아니면 그렇습니다 cat file1 >> file2
. 출력은 다음과 같을 것으로 예상됩니다.
ABC
DEF
그러나 아래와 같이 흥미로운 결과가 나왔습니다.
ABCDEF
파일을 확인해 보니 추가 공백이나 문자가 없습니다. 그런데 문자열 뒤에서 수동으로 제거하면 문자 하나도 보이지 않습니다. 좋은 결과. 나는 내가 볼 수 없는 어떤 종류의 "숨겨진" 문자나 대사가 있을 것이라고 생각했습니다.
연결해야 할 파일이 너무 많아서 귀찮았습니다. 수동으로 같은 작업을 수행할 수 없습니다.
도움을 주시면 감사하겠습니다.
답변1
paste
아마도 가장 간단한(매우 효율적인 것은 말할 것도 없습니다)이 문제를 해결할 수 있다는 뜻입니다.
printf abc >file1
printf def >file2
paste -sd\\n file[12]
abc
def
paste
순차적으로 호출 되면 -s
명명된 각 입력 파일을 차례로 읽고 paste
<tab> 또는 지정된 구분 기호 문자열에 있는 각 파일의 각 줄에 대한 출력을 읽습니다 -d
. paste
명명된 각 infile의 출력은 항상 ewline으로 끝나는 반면 , \n
여기의 -d
구분 기호도 \n
ewline으로 지정되므로 기본적으로는 cat
가져오고 내보내지만 각 파일은 항상 \n
ewline으로 끝납니다.
Peter가 아래에서 지적한 것처럼 빈 파일로 인해 paste
추가 \n
줄눈이 발생할 수 있습니다. 이것이 문제라면 실제로도 같은 sed
접근법을 적용할 수 있다.아니요이 방법:
: > file0
sed '' file[012]
abc
def
하지만 이제 이 방법을 사용하면sed
(적어도 GNU)다른 문제가 있을 수 있습니다. 어떤 sed
소원 이라도언제나다른 라인을 가져오기 전에 ewline을 작성하십시오 \n
. 그러나 만약매우연결된 입력 파일 전체 시리즈의 마지막 줄과 그 뒤에 일부 sed
s(예: GNU)가능한아니요끝에 개행 문자를 추가합니다. 예를 들어, 내 입력 파일의 경우정의그 뒤에 개행 문자가 없습니다.
그리고 만약에저것질문이군요...
sed '' file[012] | paste -sd\\n
...위의 파이프라인은 아마도 모든 기반을 포괄할 것입니다.
답변2
Peter가 말했듯이 첫 번째 파일에는 줄 끝 문자가 없습니다. 아마도 ls -l
---로 확인할 수 있을 것입니다. 그리고 그것이 정확히 세 글자라면 그게 전부입니다.
파일을 "cat"하고 줄 바꿈을 추가하려는 경우오직줄 바꿈이 없으면 설명의 좋은 트릭을 사용할 수 있습니다여기.
다음 세 가지 파일이 있는 경우:
[romano:~/tmp] % ls -l f1 f2 f3
-rw-rw-r-- 1 romano romano 3 Jul 12 14:58 f1
-rw-rw-r-- 1 romano romano 4 Jul 12 15:03 f2
-rw-rw-r-- 1 romano romano 4 Jul 12 15:03 f3
[romano:~/tmp] % cat f1 f2 f3
ABCDEF
GHI
f1
마지막 줄에는 줄 끝이 없지만 다른 줄에는 끝이 있는 경우 다음과 같이 할 수 있습니다.
[romano:~/tmp] % sed -e '$a\' f1 f2 f3
ABC
DEF
GHI
... sed
은 스트림 편집기이며 마지막 줄에는 아무것도 추가하지 않고 모든 것을 변경하지 않고 인쇄하도록 지시합니다. 그러나 sed
작동할 때 암시적으로 개행을 추가하므로 문제가 해결됩니다.
cat
+를 사용하면 echo
개행 문자가 추가됩니다.언제나. 따라서 두 가지가 있습니다.
[romano:~/tmp] % for i in f?; do cat $i; echo; done;
ABC
DEF
GHI
[romano:~/tmp] %
답변3
file1
후행 개행 문자가 없는 것 같습니다 . 파일 목록을 연결하려는 경우. 다음과 같이 각 항목을 먼저 확인하고 cat
필요한 경우 줄 바꿈을 확인할 수 있습니다.
# make some sample files
printf "%s\n" abc > file1
printf "%s" def > file2 # no trailing newline
printf "%s\n" ghi > file3
printf "%s" jkl > file4 # no trailing newline
# find files to concatenate and build a sorted array `f[]`
unset f i;
while IFS= read -r -d $'\0' path; do f[i++]="$path"
done < <(find . -type f -name 'file[0-9]' -print0 | sort -z)
# build the `cat` command
cmd=cat
tmp="$(mktemp)"; echo >$tmp # a file which contains only `\n`
for file in "${f[@]}"; do
lasthex=$(tail -c1 $file | hexdump -ve '1/1 "%02x"')
[[ -z $lasthex ]] && continue # skip enpty files
[[ $lasthex == 0a ]] && nl= || nl=" $tmp"
cmd="$cmd \"$file\"$nl"
done
# execute the `cat` command
eval "$cmd"
연결 결과는 다음과 같습니다.
abc
def
ghi
jkl
생성된 명령은 다음과 같습니다.
cat "./file1" "./file2" /tmp/tmp.z7iKccY0T9 "./file3" "./file4" /tmp/tmp.z7iKccY0T9
답변4
파일에 특수 문자가 표시됩니다 od -c filename
. 줄 바꿈은 다음과 같습니다 . Windows 또는 소스 제어가 줄 바꿈을 변경한 경우에는 을 사용하는 것을 \n
볼 수 있지만 를 사용하는 것과 다른 점은 볼 수 없습니다 . 이 문제를 해결하는 데 사용할 수 있습니다 .\r\n
od -c
cat
dos2unix filename
때때로 cat이 "-" 또는 기타 유효한 문자처럼 보이는 일련의 제어 문자를 인쇄하는 것을 볼 수 있습니다.