루프 출력 리디렉션이 파일 이름에 따라 달라지는 이유는 무엇입니까?

루프 출력 리디렉션이 파일 이름에 따라 달라지는 이유는 무엇입니까?

두 개의 파일이 있습니다: a.csvb.csv:

echo $'a_header\na1' > a.csv
echo $'b_header\nb1' > b.csv

이제 각 행의 첫 번째 행을 제거한 다음 연결하고 싶습니다.

for file in `ls *.csv`; do cat $file | tail -n +2 | cat; done 

그러나 이전 명령의 출력을 파일로 리디렉션하면 출력 파일 이름에 따라 다른 결과가 나타납니다.

for file in `ls *.csv`; do cat $file | tail -n +2 | cat; done > result
for file in `ls *.csv`; do cat $file | tail -n +2 | cat; done > result.csv

cat result
a1
b1

cat result.csv
a1
b1
b1

답변1

다음 명령이 있는 경우:

command > file

명령의 표준 출력(fd 1)은 command파일로 리디렉션됩니다 file. 파일이 없으면 파일이 생성됩니다. 명령은 일반적으로 명령 출력을 파일 설명자 1(stdout)로 리디렉션합니다.

위의 표현식(출력이 파일로 리디렉션되는 경우)을 사용하는 경우 출력 스트림이 시작되기 전에 파일이 존재해야 합니다. 따라서 bash파일을 만들고(비어 있음) stdout에 연결한 command다음 해당 파일 설명자에 쓰기를 시작합니다.

이것은 쉘에 의해 처리됩니다. 이 명령은 익명 파이프에 쓰는지 파일에 쓰는지 알지 못합니다.


다음 명령을 내리세요:

for file in `ls *.csv`; do cat $file | tail -n +2 | cat; done > result.csv

여기서 일어나는 일은 파일이 result.csv비어 있다는 것입니다. 그런 다음 (include ) for로 끝나는 각 파일을 반복합니다 . 그런 다음 최소한 파일이 처리됩니다 . then 의 두 번째 줄 . 이것이 결과 파일에 두 줄이 있는 이유입니다.csvresult.csva.csvb.csvresult.csvresult.csvb1

관련 정보