Posts Tagged ‘Linux’

h1

Iterative execution script

June 6, 2008

리눅스에서 동일한 작업을 이름 끝에 숫자가 붙은 여러 파일에 대해 반복적으로 하고 싶을 때 사용할 수 있는 shell script입니다.

#!/bin/bash
# Iterative execution script for numbered files
# http://plusha.com, 24 Mar 2007
#
# Procedure:
#   1. Modify variables - EXE, OPT, IN, OUT, NMIN, NMAX
#   2. Modify NUM format
#   3. Modify Input/Output type
#   4. Run the script
### put no space after '='

EXE=transp      # Execution file
OPT='n1=381'    # Options

IN=seismogram.          # basename of input files
OUT=trseismogram.       # basename of output files

NMIN=11         # Minimum number
NMAX=391        # Maximum number
INC=10          # Number increment

for (( i=$NMIN ; i<= $NMAX ; i=i+$INC ))
do
### NUM format
#  NUM=$( printf "%02d\n" $i )  # 01,10,...,99
NUM=$( printf "%03d\n" $i )  # 001,010,...,999
#  NUM=$( printf "%04d\n" $i )  # 0001,0010,...,9999
echo $NUM

### Input/Output type
#  $EXE $OPT   $IN$NUM   $OUT$NUM
$EXE $OPT < $IN$NUM > $OUT$NUM
#  $EXE $OPT < $IN$NUM
done

위의 내용을 그대로 실행하면 아래의 내용을 실행한 것과 같습니다.
transp n1=381 trseismogram.011
transp n1=381 trseismogram.021

transp n1=381 trseismogram.391

변수들을 바꿔서 다양하게 사용할 수 있겠죠. 만약 여러 파일들의 이름을 바꾸고 싶다면 어떻게 하면 될까요?
실행 명령을 mv로 바꾸고 옵션을 비우고 Input/output type을 첫 번 째 것으로 바꾸면 되겠죠? 그러면
mv old.001 new.001
mv old.002 new.002
mv old.003 new.003

과 같이 실행할 수 있겠죠. 하지만, 더 좋은 방법이 있습니다. ‘rename’ 명령을 사용하면 됩니다.
rename old new pattern
을 실행하면 세번째 argument의 pattern(glob pattern)에 해당하는 파일들을 모두 찾아 old라는 문자열을 new라는 문자열로 바꿔줍니다. 위의 경우에는
rename old new old.*
과 같이 실행할 수 있겠죠.

h1

Recursive touch script

May 5, 2008

touch는 recursive 하게 실행되지 않아서 불편한 경우가 있습니다.
아래 shell script를 Rtouch.sh 라고 저장하고(물론 줄 번호는 제외 - vi에서 간단하게 제거할 수 있죠)
Rtouch.sh directory
라고 실행하면 directory 내에 있는 subdirectory와 file들을 touch 해줍니다.
15번째 줄의 find와 xargs를 이용하면 touch 뿐 아니라 다른 작업도 응용해서 할 수 있습니다.

01: #!/bin/sh
02: # Recursive Touch: touch files in a directory recursively
03: #
04: if [ $# -lt 1 ]
05: then
06:   echo "  Recursive Touch: touch files in a directory\
         recursively"
07:   echo "  Usage:"
08:   echo "          $0 [directory]"
09:   echo "  Required parameter:"
10:   echo "          directory name"
11:   exit 1
12: fi
13:
14: echo "touching $1"
15: find $1 -print0 | xargs -r0 touch
16: echo "files in $1 touched!"

xargs를 알기 전, 예전에는 다음과 같은 script를 만들어서 썼었죠.

01: #!/bin/sh
02: # touch files in a directory recursively03: #
04: cd directory
05: find > tmp11
06: sed 's#\(.*\)#touch\ \1#' < tmp11 > tmp22
07: sh tmp22
08: rm tmp11 tmp22
09: echo 'directory touched!'
h1

Useful shell shortcuts

June 3, 2006

Reference

Reuse previous arguments

The ! operator gives you a quick way to refer to parts of the previous command.

!! (Full contents of previous command)

How many times have you tried to edit a file, then realize that you need to be root to do it? Use bang-bang to quickly repeat the previous command, with other commands before or after.
emacs /etc/init.d/mongrel_cluster
=> Permission Denied
sudo !!
=> Now opens the file as root

!$ (Last arg of previous command)

Sometimes I need to reuse the last argument with another command, like here where I forgot to quote a string.
wget http://weather.yahooapis.com/forecastrss?p=98117
=> wget: No Match
wget ‘!$’
=> Now it works

!^ (First argument of previous command)

I rarely use this, although it could have been used in the previous tip.
echo fish and chips
echo !^
=> fish # First argument

!:1 (Argument by number)

!:1 is the same as !^. The difference is that you can reference any element of the previous command.

echo fish and chips
=> fish and chips
echo !:1
=> fish # Same thing as !^

echo fish and chips
echo !:2
=> and # Word 2 in previous command, zero-indexed

echo fish and chips
echo !:0
=> echo # The very first word in the previous command

echo fish and chips
echo !:1-3
=> fish and chips # A range

!pattern (Repeat last command in history with pattern)

The bang is useful for re-running a command that you’ve run before. Spell out the first few letters and hit ENTER (or TAB to show the completion in tcsh). The shell will search backwards in your history until it finds a command that starts with the same letters.

I like the tcsh behavior since you can hit TAB to see what you’re asking for. Using this in bash can be more adventurous since you don’t know what command will be run until you hit ENTER.
rake test:recent

!rak
=> Runs ‘rake test:recent’ or last command starting with ‘rak’

Sets

{a,b} (A set)

How often do you rename just part of a file? The {} syntax is convenient.

mv file.{txt,xml}
=> Expands to 'mv file.txt file.xml'

mv file{,.orig}
=> Expands to 'mv file file.orig'

mkdir foo{1,2,3}
=> Expands to 'mkdir foo1 foo2 foo3'