저는 Event_42417555_2018-05-23_16\:45\:28-log.txt
다음과 같은 이름과 형식의 CSV 파일로 작업하고 있습니다.
timestamp;fullpath;event;size
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_OPEN;2324
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_ACCESS;2324
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_CLOSE_NOWRITE;2324
1521540649.02;/home/workdir/quad_list_14.json;IN_OPEN;2160
1521540649.03;/home/workdir/quad_list_14.json;IN_ACCESS;2160
1521540649.03;/home/workdir/quad_list_14.json;IN_CLOSE_NOWRITE;2160
내가 원하는 것은 정규식을 사용하여 추출된 파일 이름의 값을 기반으로 파일에 열을 추가 [0-9]{8}
하고 헤더를 제거하는 것입니다 .
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_OPEN;2324;42417555
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_ACCESS;2324;42417555
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_CLOSE_NOWRITE;2324;42417555
1521540649.02;/home/workdir/quad_list_14.json;IN_OPEN;2160;42417555
1521540649.03;/home/workdir/quad_list_14.json;IN_ACCESS;2160;42417555
1521540649.03;/home/workdir/quad_list_14.json;IN_CLOSE_NOWRITE;2160;42417555
Gnu 도구를 사용하면 다음과 같이 쉽게 표시됩니다(거의 테스트하지 않았으며 거의 확실히 따옴표 문제임).
#!/bin/bash
#$1 being the filename
JOBID=$(grep -oE "[0-9]{8}" "${1}")
sed -E "s/(.*)/\1;$JOBID/" "${1}"
나는 awk
지금까지 효과가 있었던 것으로 이것을 달성하고 싶습니다.최고:
awk -F";" 'JOBID=substr(FILENAME ,match(FILENAME,"[0-9]{8}"),8); \
BEGIN { OFS=";"} { if ($1 != "timestamp") print $0,JOBID; }' \
Event_42417555_2018-05-23_16\:45\:28-log.txt | head
timestamp;fullpath;event;size
timestamp;fullpath;event;size
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_OPEN;2324
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_OPEN;2324;42417555
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_ACCESS;2324
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_ACCESS;2324;42417555
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_CLOSE_NOWRITE;2324
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_CLOSE_NOWRITE;2324;42417555
변수가 있고 올바르게 설정되었지만 올바른 위치를 찾을 수 없습니다.
이동하면 JOBID=substr(FILENAME ,match(FILENAME,"[0-9]{8}"),8);
변수에 액세스할 수 없습니다.
여기서 문제는 파일이 두 번 처리된다는 것입니다. 한 번은 올바르게 처리되고(내 조건은 무시되지만) 또 한 번은 내 변수를 고려합니다.
답변1
파일별 속성이므로 JOBID
어떤 파일의 첫 번째 줄을 처리할 때 계산해야 하며,즉1은 언제 FNR
입니까?
awk -F";" 'BEGIN { OFS = FS }
FNR == 1 { JOBID=substr(FILENAME, match(FILENAME, "[0-9]{8}"), 8); print }
FNR > 1 { print $0, JOBID }' \
Event_42417555_2018-05-23_16\:45\:28-log.txt | head
정규 표현식의 일치 항목을 추출하는 방법에는 여러 가지가 있습니다. 저는 일반적으로 match
배열을 사용합니다.
awk -F";" 'BEGIN { OFS = FS }
FNR == 1 { match(FILENAME, "([0-9]{8})", a); JOBID = a[1]; print }
FNR > 1 { print $0, JOBID }' \
Event_42417555_2018-05-23_16\:45\:28-log.txt | head
오류 처리 기능을 갖추는 것이 더 좋습니다. 이는 match
텍스트 일치 항목을 찾고 [0-9]{8}
일치하는 값을 배열로 추출하는 데 사용됩니다 a
( match
그룹을 찾으므로 괄호가 추가됨).
AWK 구현에서 작동하는 또 다른 방법은 파일 이름을 밑줄로 분할하는 것입니다.
awk -F";" 'BEGIN { OFS = FS }
FNR == 1 { split(FILENAME, a, "_"); JOBID = a[2]; print }
FNR > 1 { print $0, JOBID }' \
Event_42417555_2018-05-23_16\:45\:28-log.txt | head
귀하 버전의 이중 출력은 JOBID=substr(FILENAME ,match(FILENAME,"[0-9]{8}"),8)
AWK 프로그램의 다른 표현식과 동일한 가중치를 갖는 완전한 표현식이고 암시적 블록(즉 print
); JOBID
항상 비어 있지 않고 0과 같은 숫자 값이 아니기 때문에 항상 일치하므로 해당 청크가 항상 처리됩니다.