나는 주어진 경로에 대한 상위 디렉터리 목록을 제공할 수 있는 bash 스크립트에서 사용할 수 있는 도구를 찾고 있습니다.
foo/bar/moocow
예를 들어, 출력하려는 입력이 있다고 가정해 보겠습니다.
foo
foo/bar
foo/bar/moocow
여러 경로를 입력하여 고유한 결과를 얻을 수 있다면 좋을 것입니다. 예를 들면 다음과 같습니다.
toolimlookingfor << EOF
dir1/file1
dir1/file2
foo/bar/moocow
EOF
산출:
dir1
dir1/file1
dir1/file2
foo
foo/bar
foo/bar/moocow
dirname
내가 찾고 있는 것과 가깝지만 직계 부모만 제공합니다. 나는 나 자신과 모든 부모의 길을 찾고 있습니다.
답변1
/tmp
폴더 내에 새 디렉터리를 만드는 데 동의하는 경우 find 명령을 사용할 수 있습니다. 이 방법을 사용하면 고유한 디렉터리 이름만 인쇄할 수도 있습니다.
#!/bin/bash
if [[ $# -eq 0 ]]; then exit; fi
mkdir -p /tmp/printnames
for i
do
mkdir -p /tmp/printnames/"$i"
done
cd /tmp/printnames
find * -type d -print
rm -r /tmp/printnames
따라서 임시 디렉터리 구조를 만든 다음 찾기를 사용하여 탐색할 수 있습니다.
답변2
표준 Python 스크립트 사용pathlib
입력 대신 매개변수를 처리하는 모듈:
#! /usr/bin/env python3
import sys
from collections import OrderedDict
from pathlib import Path
paths = OrderedDict() # to maintain ordering and skip duplicates
for arg in sys.argv[1:]:
path = Path(arg)
for subpath in reversed(path.parents):
# add the parents
paths[subpath.as_posix()] = subpath
# add the path itself
paths[path.as_posix()] = path
# we don't need '.' in the output
if '.' in paths:
paths.pop('.')
print('\n'.join(paths.keys()))
(이것은 루프를 통해 표준 입력을 사용하도록 쉽게 수정할 수 있습니다 sys.stdin
.)
예:
% ./foo.py dir1/file1 dir1/file2 foo/bar/moocow
dir1
dir1/file1
dir1/file2
foo
foo/bar
foo/bar/moocow
답변3
이 코드가 이를 수행합니다. 임시 파일을 사용하지 않습니다. 공백에 대해서는 잘 작동하지만 개행 문자는 모호합니다( 수정 \n
되도록 변경됨 \0
). \0
자동화된 프로세스에서 사용하려면 이를 사용해야 합니다. \0
Unix 파일 이름에 포함되지 않는 것이 보장되는 유일한 문자입니다.
단지 재귀적으로 사용됩니다 . dirnames
특정 을 제거/활성화하여 printf
조정할 수 있습니다. 위 또는 아래로 이동하거나 루트 노드( .
또는 /
)를 표시하지 않도록 합니다. 귀하의 예에는 루트 노드가 표시되지 않았지만 필요하다고 생각합니다. 이것이 없으면 /a/b/c
출력은 a/b/c
.
#!/bin/bash
function dirnames {
local input
local parent
input="$1"
if [[ "$input" == "" ]]
then
true
elif [[ "$input" == "." || "$input" == "/" ]]
then
printf '%s\n' "$input" #print the root node
else
#printf '%s\n' "$input" #print node (descending)
parent="$(dirname "$input")"
dirnames "$parent"
printf '%s\n' "$input" #print node (ascending)
fi
}
for d in "$@"
do
dirnames "$d"
done
사용 예
%↳ ./dirnames a/b/c
.
a
a/b
a/b/c
%↳ ./dirnames /a/b/c
/
/a
/a/b
/a/b/c
%↳
이렇게 작동하게 하려면
%↳ ./dirnames a/b/c
.
a
b
c
%↳ ./dirnames /a/b/c
/
a
b
c
%↳
그런 다음 파일을 다른 이름으로 저장 dirnames
하고 실행하십시오 sed -r -i '17 s/("[$]input")/"$(basename \1)"/' dirnames
. 이제 각 레벨의 리프만 출력하는 스크립트가 생성됩니다.
답변4
제 경우처럼 후행 슬래시(또는 다른 구분 기호)가 효과가 있다면 다음 해결 방법이 가장 간단하고 투명합니다.
pth='one/two/three'
sep='/'
# split string into array by separator
arr=($(echo $pth | tr $sep '\n'))
# loop over array and append
sub=''
for index in ${!arr[@]}
do
sub+="${arr[index]}$sep"
printf "$index \t ${arr[index]} \t $sub \n"
done
산출:
0 one one/
1 two one/two/
2 three one/two/three/