탭으로 구분 된 파일에 값 열 추가


17

특정 개수의 행이있는 파일에 값 열을 추가하는 방법 다음과 같은 입력 파일이 있습니다.

입력 파일:

SPATA17 1   217947738
LYPLAL1 1   219383905
FAM47E  4   77192838
SHROOM3 4   77660162
SHROOM3 4   77660731
SHROOM3 4   77662248

결과물 파일:

SPATA17 1   217947738 file1
LYPLAL1 1   219383905 file1
FAM47E  4   77192838  file1
SHROOM3 4   77660162  file1
SHROOM3 4   77660731  file1
SHROOM3 4   77662248  file1

이 경우 파일의 행 수까지 값 열을 추가하고 싶습니다. 값은 "file1"과 같이 일관되게 유지됩니다.

그 이유는 100 개의 파일이 있기 때문에 각 파일을 열고 열을 붙여 넣기를 원하지 않습니다. 또한 디렉토리로 이동하여 값 열을 추가하여이를 자동화 할 수있는 방법이 있습니다. 값은 파일 이름에서 나옵니다. 파일 이름은 마지막 / 첫 번째 열에서 파일의 각 행에 추가해야합니다.

답변:


22

다음과 같이 한 줄짜리 루프를 사용할 수 있습니다.

for f in file1 file2 file3; do sed -i "s/$/\t$f/" $f; done

목록의 각 파일에 sed대해 각 행의 끝에 탭과 파일 이름을 추가하는 데 사용 됩니다.

설명:

  • 은 Using -i와 플래그를 sed파일을 덮어 쓰기, 현재 위치에서 교체를 수행 할 수
  • 로 대체를 수행하십시오 s/PATTERN/REPLACEMENT/. 이 예제에서 PATTERN은 $행의 끝이며 REPLACEMENT는 \t(= TAB)이며 $f루프 변수의 파일 이름입니다. s///쉘 변수를 확장 할 수 있도록 명령은 큰 따옴표 내에 있습니다.

코드가 작동합니다. 따옴표 안에 내용을 설명 할 수 있습니까?
Ron

열로 작업하는 동안 "awk"가 사용되는 것처럼 비슷한 상황에도 'sed'가 사용됩니다. 나는 'awk'와 'sed'를 처음 사용합니다.
Ron

@Ron sed은 패턴 대체 및 내부 저장에 가장 실용적입니다. 파일 저장 요구 사항은 비교적 편리한 옵션이었습니다. 처리중인 동일한 파일에 다시 쓸 필요가없는 경우 awk일반적으로 작업하기가 훨씬 쉽습니다.
janos

개인적으로 awk입력 / 출력 필드 구분 기호가 너무 자주 트립 되므로 가능할 때마다 사용하지 않는 것이 sed좋습니다.
user5359531

11

paste명령 이있을 때 사람들이 그 강력한 도구를 추천하는 이유를 생각해보십시오 !

$ cat a
A
B
C
D
$ cat b
1
2
3
4
$ paste a b
A   1
B   2
C   3
D   4

약간의 속임수로 pasteOP의 목적으로 사용할 수 있습니다 . 그러나 파일을 대체하지 않습니다.

for f in file1 file2 file3; do 
    paste $f <(yes $f | head -n $(cat $f | wc -l)) > $f.new
done

그러면 해당 파일 이름이 각 파일의 마지막 열로 새 파일에 붙여 넣어집니다 filename.new


감사! paste반드시 숨겨진 보석입니다.
neu242

10

당신은 사용할 수 있습니다 awk:

awk '{print $0, FILENAME}' file1 file2 file3 ...

각 파일의 이름이 다르므로이 작업을 100 번 수행해야합니다. 한 번 수행 할 방법이 있습니까?
Ron

아니요, FILENAME의 변수 이며 처리 awk중인 현재 파일 이름으로 확장됩니다 awk. 하나만 수행하면 모든 파일을에 피드 할 수 있습니다 awk.
cuonglm

좋아, 그러나 출력을 각 파일의 새 파일로 보내는 방법? awk는 처리하는 동안 각 파일을 저장합니까?
Ron

가지고있는 GNU awk 4.1.0경우 나중에 -i편집 할 수 있습니다 . 그렇지 않으면 awk출력을 임시 파일로 리디렉션 한 다음 grep각 파일에서 줄을 추출 하는 데 사용해야 합니다.
cuonglm

잘 할 수 있습니다for file in *; do awk 'BEGIN{OFS="\t"}{print $0, FILENAME}' $file; done
fedorqui
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.