최상위 디렉터리의 하위 디렉터리 2개에 일부 .csv 로그 파일이 있고 각 디렉터리의 모든 .csv 로그 파일을 비우되 헤더를 유지하여 해당 파일을 만든 응용 프로그램이 파일을 다시 채울 수 있도록 하려고 합니다.
이를 사용하여 파일을 비울 수 있지만 for file in /path/to/file/*; do > $file;done
헤더도 제거됩니다!
답변1
tmpfile=$( mktemp )
for pathname in /path/to/dir/*.csv; do
head -n 1 "$pathname" >"$tmpfile"
cat "$tmpfile >"$pathname"
done
rm "$tmpfile"
즉, head -n 1
임시 파일을 사용하여 헤더를 추출한 다음(첫 번째 줄이라고 가정) 원본 파일을 자르고 임시 파일에서 헤더를 삽입합니다.
헤더가 모든 파일에서 정확히 동일한 경우:
tmpfile=$( mktemp )
set -- /path/to/dir/*.csv
head -n 1 "$1" >"$tmpfile"
for pathname do
cat "$tmpfile" >"$pathname"
done
rm "$tmpfile"
먼저 위치 매개변수를 관심 있는 파일 목록으로 설정한 다음 첫 번째 파일에서 헤더를 추출합니다. 이 루프는 위치 매개변수(CSV 파일)를 반복하고 각 매개변수를 자르고 제목을 삽입합니다.
위의 두 예에서 패턴이 /path/to/dir/*.csv
일치한다고 가정합니다.모두영향을 받는 파일. 실제 패턴의 실제 예는 다음과 같습니다.
/var/log/myprogram/dir1/*.csv /var/log/myprogram/dir2/*.csv
또는 중괄호 확장을 지원하는 셸을 사용하는 경우:
/var/log/myprogram/{dir1,dir2}/*.csv
답변2
또는 옵션을 sed
제공 하려는 경우 로 바꿀 수 있습니다 . 여기서 유지하려는 헤더 행 수는 다음 과 같습니다. 일부 구현에는 명시적으로 빈 백업 파일이 필요할 수 있습니다 .--in-place
-i
> "$file"
sed -i 4q "$file"
4
-i ''
파일 수가 너무 크지 않으면 루프를 피하고 파일 목록을 직접 전달할 수 있습니다.
sed -si 4q subdir1/*.csv subdir2/*.csv
( 암시된 s
대로 적어도 GNU sed에서는 중복될 수 있음 )-i
-s
또는 사용find
find path/to/dir -name '*.csv' -execdir sed -si 4q {} +