AIX 시스템에서 ksh88을 사용하여 많은 것을 시도했지만 아무 것도 작동하지 않았습니다.
File_A
헤더가 없는 2개의 열이 있습니다. 열 1에는 디렉터리를 생성한 사용자 그룹, 열 2에는 전체 파일 경로가 있습니다. 예를 들면 다음과 같습니다.
Userwh0c4r35 /fake/file/path/directory_name
User1234567 /another/file/path/different_dir
User0987654 /some/other/path/another_name
File_B
2개의 열이 있고 헤더는 없습니다. 열 1에는 디렉터리 크기(MB), 열 2에는 디렉터리의 부분 경로 이름이 있습니다. 예를 들면 다음과 같습니다.
2183.31 directory_name
1750.09 directory_name/subfolder
1028.14 directory_name/subfolder/sub_subfolder
3658.97 different_dir
2159.62 different_dir/subfolder
1001.01 different_dir/different_subfolder
등.
문제는 File_B
(즉, directory_name
, directory_name/subfolder
, , ...) directory_name/subfolder/sub_subfolder
에 중복된 디렉터리 이름이 있다는 것입니다.
내가 원하는 것은 파일에서 다음과 같은 출력입니다(솔직히 열의 순서는 신경 쓰지 않고 열이 모두 존재한다는 것뿐입니다).
Userwh0c4r35 /fake/file/path/directory_name 2183.31
User1234567 /another/file/path/different_dir 3658.97
이것은 충분히 간단해 보이지만 나는 그것을 알아낼 수 없었습니다. 내가 얻을 수 있는 가장 가까운 방법은 부분적으로 일치하는 두 파일에서 사용자 그룹, 전체 경로 이름 및 줄 번호를 가져오는 것입니다. 그러나 디렉터리 크기(열 1 File_B
) 는 가져올 수 없습니다 .
저를 너무 가까워졌지만 아직 거기에 도달하지 못한 코드는 다음과 같습니다(SO 및 다양한 온라인 튜토리얼에서 함께 엮음).
awk '
NR==FNR {
a[$2]=$1
next
}
{
for(i in a)
if($2 ~ i)
{print $2,a[$2],$1}
}' file_B file_A
File_A
의 열 2가 File_A
부분적으로 의 열 2와 일치하는 각 행에 중복 항목이 있는 목록을 생성합니다 File_B
. 예를 들면 다음과 같습니다.
Userwh0c4r35 /fake/file/path/directory_name
Userwh0c4r35 /fake/file/path/directory_name
Userwh0c4r35 /fake/file/path/directory_name
directory_name
( directory_name/subfolder
, , 및 각각 1개 directory_name/subfolder/sub_subfolder
)
print
제가 생각할 수 있는 모든 것을 시도해 보았 으나 소용이 없었습니다... NR,FNR,i,$0,a[$NR],a[$FNR],a[$1],a[$2],$1,$2
저도 사용해 보았지만 printf
역시 효과가 없었습니다...
답변1
당신이 원하는 것은 본질적으로 두 개의 데이터베이스 테이블을 조인하는 것입니다. 편리하게도 이 작업을 수행하는 적절한 이름의 명령이 있습니다 join
.
여기서는 필요하지 않습니다 awk
. 저는 AIX도 AIX도 없습니다 ksh88
. 이것은 Linux의 Bash이지만 빠르게 확인했습니다.AIX 매뉴얼그리고 그것이 효과가 있어야 한다고 생각했습니다.
저는 다음과 같은 테스트 환경을 준비했습니다.
$ cat filea
Userwh0c4r35 /fake/file/path/directory_name5
Userwh0c4r36 /fake/file/path/directory_name6
Userwh0c4r37 /fake/file/path/directory_name7
$ cat fileb
1234 directory_name5
2345 directory_name6
3456 directory_name7
1 단계filea
: 디렉토리 경로 이름의 마지막 부분만 포함하는 열을 추가합니다 .
$ sed 's|\(.*\)/\(.*\)|\1/\2 \2|' filea > filea.tmp
$ cat filea.tmp
Userwh0c4r35 /fake/file/path/directory_name5 directory_name5
Userwh0c4r36 /fake/file/path/directory_name6 directory_name6
Userwh0c4r37 /fake/file/path/directory_name7 directory_name7
2 단계: 두 파일을 디렉토리 이름별로 정렬합니다(이 점을 지적한 Mark Plotnick에게 감사드립니다).
$ sort -k3 filea.tmp > filea.tojoin
$ sort -k2 fileb > fileb.tojoin
3단계: AND를 사용하여 열 3( ) 및 열 2( )의 디렉터리 이름을 기준으로 join
조인합니다 .fileb
filea
fileb
$ join -1 3 -2 2 filea.tojoin fileb.tojoin > result
$ cat result
directory_name5 Userwh0c4r35 /fake/file/path/directory_name5 1234
directory_name6 Userwh0c4r36 /fake/file/path/directory_name6 2345
directory_name7 Userwh0c4r37 /fake/file/path/directory_name7 3456
선택적 4단계: cut
A는 원하지 않는 경우 첫 번째 열을 삭제합니다.
답변2
무엇을 하려는지 명확하지 않으며 예제 입력/출력은 현재 테스트에 유용하지 않지만 다음은 추측입니다.
$ cat tst.awk
BEGIN { OFS="\t" }
{
val = $1 # val = Userwh0c4r35 or 2183.31
sub(/^[^[:space:]]+[[:space:]]+/,"") # Allows spaces in directory names vs using $2
dir = $0 # dir = /fake/file/path/directory_name or directory_name/subfolder
}
NR==FNR {
sub(".*/","",dir) # dir = directory_name
dir2path[dir] = $0
dir2grp[dir] = val
next
}
{
sub("/.*","",dir) # dir = directory_name
print dir2grp[dir], dir2path[dir], val
}
$ awk -f tst.awk File_A File_B
Userwh0c4r35 /fake/file/path/directory_name 2183.31
Userwh0c4r35 /fake/file/path/directory_name 12345
Userwh0c4r35 /fake/file/path/directory_name 9876
위의 내용은 File_A의 다른 경로(예: 및 ) directory_name
끝에 동일한 콘텐츠가 나타날 수 없다고 가정 하고 다음 입력 파일에서 실행됩니다./foo/directory_name
/bar/directory_name
$ head File_*
==> File_A <==
Userwh0c4r35 /fake/file/path/directory_name
==> File_B <==
2183.31 directory_name
12345 directory_name/subfolder
9876 directory_name/subfolder/sub_subfolder
디렉터리 이름에 탭 문자가 포함될 수 있는 경우 다른 출력 형식을 사용해야 합니다. 개행 문자를 포함할 수 있는 경우 다른 입력 형식도 필요합니다.