문제

텍스트 파일 디렉토리를 통해 루프를하고 하나의 문서로 결합하려고합니다. 이것은 훌륭하게 작동하지만 텍스트 파일에는 코드 스 니펫이 포함되어 있으며 모든 형식이 왼쪽으로 무너지고 있습니다. 라인의 모든 선행 공백이 제거되었습니다.

#!/bin/sh
OUTPUT="../best_practices.textile"
FILES="../best-practices/*.textile"
for f in "$FILES"
do
  echo "Processing $f file..."
  echo "">$OUTPUT

  cat $f | while read line; do 
      echo "$line">>$OUTPUT
  done
  echo >>$OUTPUT
  echo >>$OUTPUT
done

나는 분명히 배쉬 멍청이이지만 높고 낮은 검색 후에는 적절한 솔루션을 찾을 수 없었습니다. 분명히 Bash는 일반적으로 주요 공백을 싫어합니다.

도움이 되었습니까?

해결책

대신에:

cat $f | while read line; do 
    echo "$line">>$OUTPUT
done

이 작업을 수행:

cat $f >>$OUTPUT

(라인별로 일을 해야하는 이유가 있다면 문제에 포함시키는 것이 좋습니다.)

다른 팁

다른 사람들이 지적했듯이, Read-echo 루프 대신 Cat 또는 AWK를 사용하는 것이 훨씬 더 나은 방법입니다. 공백 트리밍 문제 (그리고 당신이 우연히 발견하지 못한 다른 두 사람)를 피하고 더 빨리 달리는 것입니다. 그리고 적어도 고양이와 함께, 단순히 더 깨끗한 코드입니다. 그럼에도 불구하고, 나는 Read-Echo 루프를 제대로 작동시키는 데 찌르고 싶습니다.

먼저, 공백 트리밍 문제 : 읽기 명령은 자동으로 선행 및 후행 공백을 트림합니다. IFS 변수를 공백으로 설정하여 공백의 정의를 변경하여 고정 될 수 있습니다. 또한, 읽기는 줄 끝의 백 슬래시가 다음 줄이 연속임을 의미하며,이 라인과 함께 스 플라이싱해야한다고 가정합니다. 이 문제를 해결하려면 -r (원시) 플래그를 사용하십시오. 여기서 세 번째 문제는 에코의 많은 구현이 문자열에서 탈출 시퀀스를 해석한다는 것입니다 (예 : 실제 신약으로 바꿀 수 있음). 이 문제를 해결하려면 대신 printf를 사용하십시오. 마지막으로, 일반적인 스크립팅 위생 규칙처럼 실제로 필요하지 않을 때는 고양이를 사용해서는 안됩니다. 대신 입력 리디렉션을 사용하십시오. 이러한 변경으로 내부 루프는 다음과 같습니다.

while IFS='' read -r line; do 
  printf "%s\n" "$line">>$OUTPUT
done <$f

... 주변 스크립트에는 몇 가지 다른 문제가 있습니다. 사용 가능한 .Textile 파일의 목록으로 파일을 정의하려고 시도하는 줄은 그 주위에 따옴표가 있습니다. 즉, 실제 파일 목록으로 확장되지 않습니다. 이를 수행하는 가장 좋은 방법은 배열을 사용하는 것입니다.

FILES=(../best-practices/*.textile)
...
for f in "${FILES[@]}"

(그리고 $ F의 모든 발생은 파일 이름에 공백이나 다른 재미있는 캐릭터가있는 경우 두 배로 인용해야합니다. 스크립트에 정의되기 때문에 실제로 $ 출력으로도 수행해야합니다. 실제로 안전합니다. 그만두 다.)

마지막으로, a echo "">$OUTPUT 매번 출력 파일을 지우는 루프 오버 파일의 상단 근처에서 (즉, 마지막 .Textile 파일 만 포함); 이것은 루프 전에 이동해야합니다. 여기에 의도가 파일의 시작 부분에 단일 빈 줄을 넣는 것이 확실하지 않거나 파일 사이 (그리고 처음에는 하나와 끝에 2 개) 사이에 3 개의 빈 줄이 있습니다. 적절한 교체품입니다. 어쨌든, 다음은 다음과 같은 모든 문제를 해결 한 후에 내가 할 수있는 일이 있습니다.

#!/bin/sh
OUTPUT="../best_practices.textile"
FILES=(../best-practices/*.textile)

: >"$OUTPUT"
for f in "${FILES[@]}"
do
  echo "Processing $f file..."
  echo >>"$OUTPUT"

  while IFS='' read -r line; do 
    printf "%s\n" "$line">>"$OUTPUT"
  done <"$f"

  echo >>"$OUTPUT"
  echo >>"$OUTPUT"
done

그것은 파일을 결합하는 지나치게 비싼 방법입니다.

cat ../best-practices/*.textile >  ../best_practices.textile

연결대로 각 파일에 공백 (Newline)을 추가하려면 awk를 사용하십시오.

awk 'FNR==1{print "">"out.txt"}{print > "out.txt" }' *.textile

또는

awk 'FNR==1{print ""}{print}' file* > out.txt

이를 통해 원래 스크립트에서 수행 한 것처럼 각 입력 파일간에 최신을 산재 할 수 있습니다.

for f in $FILES; do echo -ne '\n\n' | cat "$f" -; done > $OUTPUT

주목하십시오 $FILES 이것에 대해 인용되지 않음 (그렇지 않으면 여분의 최신 라인은 모든 출력이 끝날 때 한 번만 나타납니다). $f 파일 이름으로 공간을 보호하기 위해 인용해야합니다.

정답, IMO는입니다 이것, 아래 재생 :

while IFS= read line; do
    check=${line:0:1}
done < file.txt

실제 파일뿐만 아니라 다른 명령에서 입력이 파이프가있는 상황을 처리합니다.

아래 그림과 같이 리디렉션을 단순화 할 수도 있습니다.

#!/bin/bash
OUTPUT="../best_practices.textile"
FILES="../best-practices/*.textile"
for f in "$FILES"
do
  echo "Processing $f file..."
  {
  echo

  while IFS= read line; do 
      echo "$line"
  done < $f
  echo
  echo;
  } > $OUTPUT
done
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top