나는 많은 파일을 다운로드하고 컴파일하는 프로젝트를 가지고 있습니다. 이 파일에 대해 내가 할 수 있는 가정은 다음과 같습니다.
- 최상위 디렉터리는 하나만 있습니다.
- 폴더 이름이 tar.xz/gz 파일 이름과 반드시 일치할 필요는 없습니다. 즉, Something-1.3.5a.tar.gz가 Something-1.3.5라는 폴더로 추출될 수 있습니다.
입력량을 줄이기 위해 다음을 수행하는 작은 스크립트를 작성했습니다.
- tar.xz/gz 파일 추출
- cd로 디렉토리에 들어가세요
내 현재 해킹은 다음과 같은 작업을 수행하는 것입니다.
test1=$(tar -axvf something-1.3.5a.tar.gz)
cd $(echo $test1 | cut -f1 -d" ")
기본적으로 이것이 하는 일은 추출의 출력을 캡처하고 첫 번째 줄(최상위 디렉터리)을 가져온 다음 거기에 CD를 넣는 것입니다.
그래서 제 질문은 이 작업을 수행하는 더 깨끗하고 더 나은 방법이 있습니까?
답변1
#!/bin/sh
Dir_name=`tar -tzf something-1.3.5a.tar.gz | head -1 | cut -f1 -d"/"`
echo $Dir_name
tar options details,
-t, --list
-z, --gzip, --ungzip filter the archive through gzip
-f, --force-local archive file is local even if has a colon
여기서는 tar의 파일 목록을 가져오고 head -1
cmd를 사용하여 첫 번째 줄을 가져온 다음 cmd를 잘라 첫 번째 필드를 추출합니다.
답변2
최상위 디렉토리가 있지만 거기에 아무 것도 없다면 tar를 실행하기 전에 어떤 디렉토리가 있는지 기억하고 tar를 실행한 후에 무엇이 있는지 확인할 수 있습니다(아무도 디렉토리를 변경하지 않았다고 가정).
# ksh terminology: set -A BEFORE .*/ */
BEFORE=(.*/ */)
tar -xf blah blah blah
AFTER=(.*/ */)
# We can make it O(n), since glob outputs can be assumed to be sorted.
# Do it.
for (( i = 0; i < "${#BEFORE[@]}"; i++ )); do
[ "${BEFORE[i]}" == "${AFTER[i]}" ] || break
done
cd "${AFTER[i]}"
for
이는 산술 , 0부터 시작하는 배열 인덱싱을 사용하고 ${#arr[@]}
배열 멤버 수에 액세스하는 모든 쉘에서 작동합니다 .
사실상 매칭이 없는 곳 */
까지 확장이 가능하기 때문에 문제가 있다 . (태그 때문에 bash를 사용한다고 가정하면) 이것을 설정할 수 */
있습니다 .bash
shopt -s nullglob
와일드카드를 디렉터리로 제한 하면 */
파일에 대해 걱정할 필요가 없습니다. 추가 파일은 여전히 하나의 디렉터리로 만듭니다. :)
답변3
tar.bz2 파일을 사용하면 다음과 같은 결과가 나오지 않습니다.
0 0 2019-04-02 17:20 folder name
-tf 옵션을 사용하고 있습니다.
tar -tf file_name.tar.bz2 | head -1 | cut -f1 -d"/"