sed 마법이 필요합니다. 표시된 줄을 파일의 시작 부분으로 이동하세요.

sed 마법이 필요합니다. 표시된 줄을 파일의 시작 부분으로 이동하세요.

나는 마법이 절실히 필요하다는 것을 깨달았습니다 sed.진짜나는 앉아서 이것을 배워야 한다). 줄이 많은 파일이 있습니다. 검토한 후 줄 시작 부분에 별표(*)를 추가하여 일부 줄을 표시했습니다.

(가능하다면) 내가 하고 싶은 몇 가지 트릭은 sed모든 마커 라인을 파일의 시작 부분(또는 끝 - 까다롭지 않음)으로 이동하여 블록을 형성하는 것입니다. 표시되지 않은 다른 선은 방해받지 않아야 합니다.

어떻게 이런 일을 할 수 있나요 sed? sed텍스트 이동을 위한 버퍼가 있다는 것을 알고 있습니다 .

답변1

sed가 필요한가요? 소스 파일을 두 번 살펴보는 것이 괜찮다면 grep을 사용하여 쉽게 수행할 수 있습니다.

예를 들어

grep '^\*' input > outputfile
grep -v '^\*' input >> outputfile

답변2

파일 크기에 따라 다음을 수행할 수 있습니다.

sed '/^*/!H;//p;$!d;g;s/\n//'

H일치하지 않는 오래된 공간 라인 에 쌓여 있습니다 /^*/. 해당 일치 항목은 p입력에 나타나는 대로 인쇄됩니다. 그런 다음 !마지막 행이 아닌 모든 행이 출력에서 ​​제거됩니다 $. d마지막 줄에서는 g패턴 공간을 덮어써서 공간을 보존한 다음, 첫 번째 줄이 매번 추가 문자를 생성하므로 첫 번째 \newline 문자가 대체됩니다 .s/\n//H

H그러나 이는 이미 모든 행을 이전 공간 에 저장하고 있기 때문에 큰 버퍼가 필요합니다 . 한편, 이...

sed '/^*/p;$!d;g;r file' <file    |
sed -e '1,/^$/{/./p;d' -e '};/^*/d'

...그런 요구 사항은 없습니다.

첫 번째는 마지막 줄 까지 일치하는 줄만 sed p인쇄하고 , 마지막 줄에서는 빈 줄을 인쇄한 다음 전체 입력 파일을 다시 읽습니다./^*/$r

두 번째는 sed먼저 첫 번째 줄부터 첫 번째 빈 줄까지의 줄 범위 내에서 작동하여 p최소한 단일 문자와 일치하는 모든 줄을 인쇄한 다음 d일괄 처리를 삭제합니다. 첫 번째 빈 줄을 만난 후 d일치하는 모든 줄을 삭제합니다 /^*/.

답변3

이 작업을 수행할 필요는 없으며 sed기본 grep을 사용하여 별표(*) 줄을 맨 위로 끌어올 수 있습니다. 다음 파일이 있다고 가정해 보겠습니다.

$ cat sample.txt 
1
2
3
4
* 5
* 6
* 7
8
9
10

이제 grep이전 example.txt 파일에 별표(*) 줄을 추가합니다.

$ cat <(grep '*' sample.txt) <(grep -v '*' sample.txt)
* 5
* 6
* 7
1
2
3
4
8
9
10

위의 명령은 2개의 grep을 실행합니다. 첫 번째 명령은 별표가 있는 모든 줄을 꺼내고, 두 번째 명령은 별표가 아닌 모든 줄을 가져옵니다. 이 두 명령의 출력은 명령에 대한 입력으로 기호 리디렉션을 cat사용합니다 .<()

대체 방법

cat + 2 하위 쉘을 사용하지 않으려면 @terdon이 제안한 대로 수행할 수 있습니다.

$ grep '*' sample.txt; grep -v '*' sample.txt

sample.txt그러면 별표(*)가 포함된 모든 줄이 추출되고 , 그 뒤에는 별표(*)가 포함되지 않은 모든 줄이 표시됩니다.

인용하다

답변4

두 블록 사이에 빈 줄이 있어도 괜찮다면:

sed -n -e '/^* /{H;$!d}' -e '/^* /!p' -e '${g;p}'

혹은 그 반대로도

sed -n -e '/^* /{p;$!d}' -e '/^* /!H' -e '${g;p}' file    

관련 정보