Skip to content

Instantly share code, notes, and snippets.

@victoriastuart
Last active July 26, 2017 00:47
Show Gist options
  • Save victoriastuart/7457b2727d21a37b7a79eb9a957b988d to your computer and use it in GitHub Desktop.
Save victoriastuart/7457b2727d21a37b7a79eb9a957b988d to your computer and use it in GitHub Desktop.
PROBLEM: tag a file, at the top of the file, with the base name of the parent directory.
SOLUTION 1 -- non-empty files:
$ bn=${PWD##*/} ## bn: basename
$ sed -i '1s/^/'"$bn"'\n/' <filename>
SOLUTION 2a -- empty files:
## sed fails on empty files; solution:
$ printf "${PWD##*/}\n" >> <filename>
SOLUTION 2b -- recurse over directory:
$ for file in *; do printf "${PWD##*/}\n" >> $file; done
==============================================================================
PROBLEM: tag a file, at the top of the file, with the base name of the parent directory.
[victoria@victoria Cancer]$ pwd
/home/victoria/Cancer
----------------------------------------
SOLUTION 1 -- non-empty files:
[victoria@victoria Cancer]$ l
total 8.0K
-rw-r--r-- 1 victoria victoria 33 Mar 23 17:38 cancer1
-rw-r--r-- 1 victoria victoria 26 Mar 23 17:39 cancer2
[victoria@victoria Cancer]$ cat cancer1
aaa
bbb
[victoria@victoria Cancer]$ cat cancer2
ccc
ddd
[victoria@victoria Cancer]$ ## bn: basename
[victoria@victoria Cancer]$ bn=${PWD##*/}
[victoria@victoria Cancer]$ pwd
/home/victoria/Cancer
[victoria@victoria Cancer]$ echo $bn
Cancer
[victoria@victoria Cancer]$ sed -i '1s/^/tag: '"$bn"'\n/' cancer1
[victoria@victoria Cancer]$ sed -i '1s/^/tag: '"$bn"'\n/' cancer2
[victoria@victoria Cancer]$ cat cancer1
tag: Cancer
aaa
bbb
[victoria@victoria Cancer]$ cat cancer2
tag: Cancer
ccc
ddd
[victoria@victoria Cancer]$ rm -f cancer*
----------------------------------------
SOLUTION 2a -- empty files:
[victoria@victoria Cancer]$ touch cancer1
[victoria@victoria Cancer]$ touch cancer2
[victoria@victoria Cancer]$ cat cancer1
[victoria@victoria Cancer]$ cat cancer2
## sed fails on empty files:
[victoria@victoria Cancer]$ sed -i '1s/^/tag: '"$bn"'\n/' cancer1
[victoria@victoria Cancer]$ sed -i '1s/^/tag: '"$bn"'\n/' cancer2
[victoria@victoria Cancer]$ cat cancer1
[victoria@victoria Cancer]$ cat cancer2
## Solution:
[victoria@victoria Cancer]$ printf "tag: ${PWD##*/}\n" >> cancer1
[victoria@victoria Cancer]$ printf "tag: ${PWD##*/}\n" >> cancer2
[victoria@victoria Cancer]$ cat cancer1
tag: Cancer
[victoria@victoria Cancer]$ cat cancer2
tag: Cancer
[victoria@victoria Cancer]$ rm -f cancer*
----------------------------------------
SOLUTION 2b -- recurse over directory:
[victoria@victoria Cancer]$ touch cancer1
[victoria@victoria Cancer]$ touch cancer2
[victoria@victoria Cancer]$ for file in *; do printf "tag: ${PWD##*/}\n" >> $file; done
[victoria@victoria Cancer]$ cat cancer1
tag: Cancer
[victoria@victoria Cancer]$ cat cancer2
tag: Cancer
## Again:
[victoria@victoria Cancer]$ for file in *; do printf "tag: ${PWD##*/}\n" >> $file; done
[victoria@victoria Cancer]$ cat cancer1
tag: Cancer
tag: Cancer
[victoria@victoria Cancer]$ cat cancer2
tag: Cancer
tag: Cancer
[victoria@victoria Cancer]$
----------------------------------------
Solutions loosely cobbled from:
A1 in: http://stackoverflow.com/questions/10654135/take-the-last-part-of-the-folder-path-in-shell
A1, A2 in: http://stackoverflow.com/questions/9533679/how-to-insert-a-text-at-the-beginning-of-a-file
A2 in: https://unix.stackexchange.com/questions/69112/how-can-i-use-variables-when-doing-a-sed/69113#69113
https://www.cyberciti.biz/faq/bash-loop-over-file/
==============================================================================
ADDENDA:
echo $PWD
/home/victoria
printf "${PWD##*/}\n" ## need the newline ( \n ) to see the output
victoria
pwd
/home/victoria
dirname $(pwd)
/home/victoria
basename $(pwd)
victoria
dirname $PWD
/home
basename $PWD
victoria
------------------------------------------------------------------------------
Note: I considered simply using
basename $PWD
or
basename $(pwd)
... however, my rationale for
${PWD##*/}
is found here:
http://stackoverflow.com/questions/1371261/get-current-directory-name-without-full-path-in-bash-script/1371283#1371283
"No need for basename, and especially no need for a subshell running pwd (which adds an extra,
and expensive, fork operation); the shell can do this internally using parameter expansion ..."
==============================================================================
http://lists.claws-mail.org/pipermail/users/2017-March/thread.html#18865
http://lists.claws-mail.org/pipermail/users/2017-March/018865.html
Q. re: tags (tagging locally-saved messages for use outside Claws)
printf is faster with or without bash:
$ cat dash.sh
#!/bin/dash
for i in `seq 1 1000`
do
basename "$PWD" >/dev/null
done
exit
$ cat bash.sh
#!/bin/bash
for i in `seq 1 1000`
do
printf "${PWD##*/}\n" >/dev/null
done
exit
$ time ./dash.sh
real 0m0.468s
user 0m0.010s
sys 0m0.053s
$ time ./bash.sh
real 0m0.042s
user 0m0.033s
sys 0m0.007s
0.468/0.042 = 11.1428 real-time difference,
[basename "$PWD"] vs. [printf "${PWD##*/}\n"]
http://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1
Real is wall clock time - time from start to finish of the call. This is all
elapsed time including time slices used by other processes and time the
process spends blocked (for example if it is waiting for I/O to complete).
----------------------------------------
$ cat dash.sh
#!/bin/dash
for i in `seq 1 1000`
do
printf "${PWD##*/}\n" >/dev/null
done
exit
$ cat bash.sh
#!/bin/bash
for i in `seq 1 1000`
do
basename "$PWD" >/dev/null
done
exit
$ time ./dash.sh
real 0m0.017s
user 0m0.007s
sys 0m0.007s
$ time ./bash.sh
real 0m0.531s
user 0m0.030s
sys 0m0.063s
0.531/.017 = 31.2352-fold difference,
[basename "$PWD"] vs. [printf "${PWD##*/}\n"]
==============================================================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment