여러 레코드가 포함된 파일이 있는데 각 레코드에는 여러 필드가 있습니다. 파일의 내용은 다음과 같습니다.
# cat inputfile
name: AAA
age: 38
city: C1
state: S1
age: 29
city: C2
name: BBBbbbB
state: S2
state: S3
age: 21
city: C3
name: ccccccC
쉘 스크립트의 매개변수에 지정된 순서대로 각 레코드의 필드를 정렬하고 싶습니다.
다음과 같은 스크립트를 실행하면:
# sh sortout.sh <inputfile> name age city state
출력은 다음과 같아야 합니다.
name: AAA
age: 38
city: C1
state: S1
name: BBBbbbB
age: 29
city: C2
state: S2
name: ccccccC
age: 21
city: C3
state: S3
답변1
단락 모드에서 작업할 때 Perl
이는 Perl이 이 옵션을 사용하여 한 번에 한 단락씩 먹도록 하는 것을 의미합니다 -00
.
그런 다음 현재 레코드에서 첫 번째 필드(콜론으로 구분)를 가져와 해시에 저장합니다.
$ perl -l -00ane '
my %h = reverse /^(([^:]+):.*)$/mg;
print $h{$_} for qw/name age city state/;
' input.file
특정 요구 사항에 따라 다음을 수행할 수 있습니다.
cat - <<\eof > code.sh
if=$1;shift
perl -ls -00ane '
my %h = reverse /^(([^:]+):.*)$/mg;
print $h{$_} for split /\s+/, $order;
' -- -order="$*" "$if"
eof
코드 파일을 생성한 후 실행합니다.
sh code.sh inputfile name age city state
답변2
당신은 Perl을 모르기 때문에 좀 더 장황하게 설명하겠습니다.
첫째, Perl은 입력 파일을 가져와 명령을 통해 변환하여 원하는 출력을 생성하는 Linux 유틸리티입니다.
일반적으로 Perl은 입력 파일을 한 번에 한 줄씩 확인합니다. 한 줄은 ASCII 문자 \012
(개행 문자라고도 함)로 다음 줄과 \n
구분됩니다 . 하지만 이 경우에는 한 번에 한 단락씩 읽는 것이 좋습니다. Perl은 para를 어떻게 식별합니까?
-00
옵션은 단락을 처리합니다. 현재 레코드 스칼라에 저장됩니다.$_
이제 레코드에는 여러 행이 포함되어야 합니다.
^....$ ^...$ ^....$
나는 그것을 기본적으로 연속적인 선의 섬 이라고 상상합니다 . 섬은 \n으로 구분됩니다.
사용된 Perl 옵션:
-l
이는 두 가지 작업을 수행합니다. 현재 레코드 $_에서 입력 레코드 구분 기호를 제거하고 인쇄할 때 다시 넣습니다.
$/ = $\ = "\n"
-s
그러면 기본 명령줄 스위치 구문 분석이 활성화됩니다. 이를 통해 명령줄 자체에서 변수가 인쇄되는 순서를 지정할 수 있습니다.
-00
예 IRS 구분 기호는 단락 모드 = 빈 문자열로 설정됩니다. 그러면 입력 데이터에서 한 번에 한 단락씩 추출되어 $_
for의 각 반복마다 저장됩니다.
-n
이렇게 하면 파일 주위에 루프가 생깁니다. 즉, 입력 파일(실제로는 파일 핸들이지만 이는 우리 수준에서는 중요하지 않음)에서 읽게 되지만 변환이 모두 현재 레코드에 적용되면 읽히지 않습니다. 마지막에 인쇄됩니다. 이 작업은 명시적으로 수행해야 합니다.
-e
이 옵션은 다음에 나오는 내용이 현재 레코드에 적용될 유효한 Perl 코드임을 Perl에게 알려줍니다.
--
=> Perl 명령줄 옵션의 끝, 스위치(대시로 시작), 파일 순입니다. 파일 이름이 대시로 시작될 가능성이 있는 경우 ./로 시작하고 전체 또는 상대 경로를 제공하거나 --
스위치 끝을 나타내는 다른 경로를 입력하는 것이 좋습니다 .
이제 algorithm
그 부분은 다음과 같습니다.
my %h = reverse /^(([^:]+):. *)$/mg;
%
Perl에서 해시 또는 연관 배열은 이름 앞의 백분율로 식별됩니다. 따라서 우리의 경우에는 해시를 작성 %h
하고 그 앞에 a를 배치합니다 my
. 즉, 다음 레코드를 읽을 때마다 해시가 어휘적이며 if 범위를 종료한다는 의미입니다. 이는 각 레코드에 대해 완전히 새로운 해시가 생성된다는 것을 의미합니다.
이 표현은 무엇을 /..../mg
의미하나요? 첫째, 모든 정규 표현식은 항상 if 연산자를 통해 일부 스칼라 변수 또는 표현식과 연결됩니다 =~
. 하지만 여기서는 하나도 보이지 않습니다. $_
현재 레코드를 의미하는 변수에 암시적으로 바인딩됩니다 .
계속됩니다- -