tr not impacting file command output - file

If I run:
$ ls -l /tmp
total 16
drwxr-xr-x 2 noaccess noaccess 177 Nov 18 09:53 hsperfdata_noaccess
drwxr-xr-x 2 root root 117 Nov 18 09:53 hsperfdata_root
I get the expected result running:
]$ ls -l /tmp | tr -s '[:space:]'
total 16
drwxr-xr-x 2 noaccess noaccess 177 Nov 18 09:53 hsperfdata_noaccess
drwxr-xr-x 2 root root 117 Nov 18 09:53 hsperfdata_root
Yet tr will not impact file output:
$ file /tmp/dummy
/tmp/dummy: empty file
$ file /tmp/dummy | tr -s '[:space:]'
/tmp/dummy: empty file
(the same if I use [:blank:])
I was expecting:
$ file /tmp/dummy | tr -s '[:space:]'
/tmp/dummy: empty file
Am I misusing file? tr? Must I awk? I'm using bash 3.2.51 on SunOS 5.10 and would like to tell XML and gz files apart.

The Solaris 5.10 version of file is producing output that uses tabs instead of spaces:
$ touch /tmp/dummy
$ file /tmp/dummy | cat -vet
/tmp/dummy:^Iempty file$
$
In this case, tr -s squashes a single tab character down to a single tab character...

Related

How to remove space for files in directory

I have these 2 space files in the below directory and want to remove space for these filenames
/home/sterlingadmin/
-rw-rw-r-- 1 sterlingadmin sterlingadmin 99 Jan 3 14:32 output test.txt
-rw-rw-r-- 1 sterlingadmin sterlingadmin 24 Dec 4 10:00 space test.txt
I try to use below find command to remove space for the files but its not reflecting for the files
[sterlingadmin#$
find -name "* *" |tr -d "[:blank:]"
./outputtest.txt
./delspace.txt
[sterlingadmin#$
ls -lrt
-rw-rw-r-- 1 sterlingadmin sterlingadmin 99 Jan 3 14:32 output test.txt
-rw-rw-r-- 1 sterlingadmin sterlingadmin 24 Dec 4 10:00 space test.txt'
Please advise if any solution for this issue. thank you.

I can see file size but not able to open the file

I can file size in MBs but when I am trying to open the file I can't ... saying can't find file.
while read line; do echo $line # or whaterver you want to do with the $line variable
cat $line | grep "PROCEDURE" > result3.txt
chmod 777 result3.txt
done < xreflist.txt;
To be able to find the file size, you need permission to read the directory.
To be able to open the file, you need permission to read the file.
It is perfectly possible to be able to do the one without the other.
$ mkdir junk
$ cd junk
$ echo "Hello World" > no-permission
$ chmod 0 no-permission
$ ls -la
total 8
drwxr-xr-x 3 jonathanleffler staff 96 Dec 29 11:34 .
drwxr-xr-x 18 jonathanleffler staff 576 Dec 29 11:34 ..
---------- 1 jonathanleffler staff 12 Dec 29 11:34 no-permission
$ cat ./no-permission
cat: ./no-permission: Permission denied
$ rm -f ./no-permission
$ cd ..
$ rmdir junk
$

trying to run arbitrary commands and parse their output

here is part of code
scanf("%[^\n]%*c",command);
int pid;
pid=fork();
if (pid == 0) {
// Child process
char *argv[]={command ,NULL};
execvp(argv[0], argv);
exit (0);
}
When I give as input ls I want as output
1 copy of mysh1.c mysh1.c mysh3.c mysh.c New Folder
a.out helpmanual.desktop mysh2.c mysh4.c New File
and when i give ls -l /tmp
i'm waiting
total 12
-rw------- 1 antre antre 0 Nov 4 17:31 config-err-KT9sEZ
drwx------ 2 antre antre 4096 Nov 4 19:21 mozilla_antre0
drwx------ 2 antre antre 4096 Jan 1 1970 orbit-antre
drwx------ 2 antre antre 4096 Nov 4 17:31 ssh-HaOFtKdeIQnQ `
but i take:
1 copy of mysh1.c mysh1.c mysh3.c mysh.c New Folder
a.out helpmanual.desktop mysh2.c mysh4.c New File
It seems that you're trying to parse the output of ls -l in a C program for some reason.
That's unlikely to be the “right” thing to do. The usual mechanism is to use opendir and readdir to read the directory file, directly.
If you have some truly strange situation in which you cannot opendir (the only case that comes to mind is if you're running ls on a remote system, eg, over ssh), there is a mode in GNU ls specifically for producing an output record format that can be parsed by another program.
From the GNU coreutils info:
10.1.2 What information is listed
‘-D’
‘--dired’
With the long listing (‘-l’) format, print an additional line after
the main output:
//DIRED// BEG1 END1 BEG2 END2 ...
The BEGN and ENDN are unsigned integers that record the byte
position of the beginning and end of each file name in the output.
This makes it easy for Emacs to find the names, even when they
contain unusual characters such as space or newline, without fancy
searching.
If directories are being listed recursively (‘-R’), output a
similar line with offsets for each subdirectory name:
//SUBDIRED// BEG1 END1 ...
Finally, output a line of the form:
//DIRED-OPTIONS// --quoting-style=WORD
where WORD is the quoting style (*note Formatting the file
names::).
Here is an actual example:
$ mkdir -p a/sub/deeper a/sub2
$ touch a/f1 a/f2
$ touch a/sub/deeper/file
$ ls -gloRF --dired a
a:
total 8
-rw-r--r-- 1 0 Jun 10 12:27 f1
-rw-r--r-- 1 0 Jun 10 12:27 f2
drwxr-xr-x 3 4096 Jun 10 12:27 sub/
drwxr-xr-x 2 4096 Jun 10 12:27 sub2/
a/sub:
total 4
drwxr-xr-x 2 4096 Jun 10 12:27 deeper/
a/sub/deeper:
total 0
-rw-r--r-- 1 0 Jun 10 12:27 file
a/sub2:
total 0
//DIRED// 48 50 84 86 120 123 158 162 217 223 282 286
//SUBDIRED// 2 3 167 172 228 240 290 296
//DIRED-OPTIONS// --quoting-style=literal
Note that the pairs of offsets on the ‘//DIRED//’ line above
delimit these names: ‘f1’, ‘f2’, ‘sub’, ‘sub2’, ‘deeper’, ‘file’.
The offsets on the ‘//SUBDIRED//’ line delimit the following
directory names: ‘a’, ‘a/sub’, ‘a/sub/deeper’, ‘a/sub2’.
Here is an example of how to extract the fifth entry name,
‘deeper’, corresponding to the pair of offsets, 222 and 228:
$ ls -gloRF --dired a > out
$ dd bs=1 skip=222 count=6 < out 2>/dev/null; echo
deeper
Note that although the listing above includes a trailing slash for
the ‘deeper’ entry, the offsets select the name without the
trailing slash. However, if you invoke ‘ls’ with ‘--dired’ along
with an option like ‘--escape’ (aka ‘-b’) and operate on a file
whose name contains special characters, notice that the backslash
is included:
$ touch 'a b'
$ ls -blog --dired 'a b'
-rw-r--r-- 1 0 Jun 10 12:28 a\ b
//DIRED// 30 34
//DIRED-OPTIONS// --quoting-style=escape
If you use a quoting style that adds quote marks (e.g.,
‘--quoting-style=c’), then the offsets include the quote marks. So
beware that the user may select the quoting style via the
environment variable ‘QUOTING_STYLE’. Hence, applications using
‘--dired’ should either specify an explicit
‘--quoting-style=literal’ option (aka ‘-N’ or ‘--literal’) on the
command line, or else be prepared to parse the escaped names.
i just only needed to use strtok

unix shell : create different tar files using a string in a array

We have services that generate files named with modules names. For ex., acqDou module generates
acqDou_0001.out
acqDou_08981.out
acqDou_23423.out
The acq_cheat module generates files with almost same name, but last numbering is a bit diffrent.
My Requirment is to tar these files on the basis of module names, one tar file per module, such as acqDou.tar and acq_cheat.tar
Below is the programm I attmepted:
cd /home/swap/output/outfiles
for i in *;
do
j=`echo $i | grep -v 'out$'`
if [ -z $j ];
then continue;
fi
count1=$(echo $i | tr -d -c '_' | wc -m)
if [ $count1 -eq 2 ]
then
two=`ls -1 $i | cut -d'_' -f2 | cut -d'.' -f1 | uniq`
else
two=`ls -1 $i | cut -d'_' -f1 | cut -d'.' -f1 | uniq`
fi
_FILE="${_FILE} $two"
done
_FILE2=`echo "${_FILE[#]}" | tr ' ' '\n' | sort -u | tr '\n' ' '`
echo "${_FILE2}"
for m in "${_FILE2}"
do
ls -lrt *${m}*.x
tar -cpf $m.tar /home/swap/output/outfiles/*${m}*
done
}
In case you can distinguish the files by their name, the solution can be so simple straightforward:
tar cf acqDou.tar acqDou*.out*
tar cf acq_cheat.tar acq_cheat*.out*
If there are several such modules, you can even apply a simple for loop to process them:
for m in acqDou acq_cheat
do
tar cf $m.tar ${m}*.out*
done
Make tars for all possible module types present in the directory - in one shot.
lets say you have modules named as.. acqDou, acqDumb, acqcheat, acqfunny - In module_XXXX.out format.
something which may looks like this, as shown below. So i got 4 modules and 500 files of each of them in the directory. They all are empty, but it doesn't matter.
>Wed Oct 05|01:15:13|gaurav#[STATION]:/root/ga/scripts/temp/tmp % ls -lrtha *.out|head -7 ; echo ; ls -lrtha |tail -8
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDou_0.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDumb_0.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqcheat_0.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqfunny_0.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDou_1.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDumb_1.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqcheat_1.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDumb_498.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqcheat_498.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqfunny_498.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDou_499.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqDumb_499.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqcheat_499.out
-rw-rw-r--. 1 gaurav gaurav 0 Oct 5 00:58 acqfunny_499.out
drwxrwxr-x. 2 gaurav gaurav 64K Oct 5 01:14 .
>Wed Oct 05|01:15:30|gaurav#[STATION]:/root/ga/scripts/temp/tmp %
In order to achieve the objective:
we can list the files, strip off the numbers (using sed), sort and unique the list (which gives the possible present module names in the directory) and then feed it to a while loop, to read module names one by one .. and then generate our output tarfile, module name wise and having files of that module only.
Here is the command:
ls *.out |sed 's/[0-9]//g'|sort|uniq|sed 's/_.out//g'|while read module
do
tar -cvf ${module}.tar ${module}*
done
We get something like this, once we finish.
>Wed Oct 05|01:16:43|gaurav#[STATION]:/root/ga/scripts/temp/tmp % ls -lrth *.tar
-rw-rw-r--. 1 gaurav gaurav 260K Oct 5 01:16 acqcheat.tar
-rw-rw-r--. 1 gaurav gaurav 260K Oct 5 01:16 acqDou.tar
-rw-rw-r--. 1 gaurav gaurav 260K Oct 5 01:16 acqDumb.tar
-rw-rw-r--. 1 gaurav gaurav 260K Oct 5 01:16 acqfunny.tar
>Wed Oct 05|01:16:48|gaurav#[STATION]:/root/ga/scripts/temp/tmp %
4 tar files have been created, with their module names. And it contains its respective module files. Let us see by using tar -tvf command. I will run it on all tar files and just take 2 lines as output, per file.
>Wed Oct 05|01:18:29|gaurav#[STATION]:/root/ga/scripts/temp/tmp % ls *.tar|while read file
do
echo ;echo "Looking inside file: $file"
tar -tvf $file|head -2
done
Looking inside file: acqcheat.tar
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqcheat_0.out
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqcheat_100.out
Looking inside file: acqDou.tar
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqDou_0.out
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqDou_100.out
Looking inside file: acqDumb.tar
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqDumb_0.out
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqDumb_100.out
Looking inside file: acqfunny.tar
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqfunny_0.out
-rw-rw-r-- gaurav/gaurav 0 2016-10-05 00:58 acqfunny_100.out
>Wed Oct 05|01:18:42|gaurav#[STATION]:/root/ga/scripts/temp/tmp %
We do really have 500 files in each tar file. Let us just confirm that too.
>Wed Oct 05|01:18:42|gaurav#[STATION]:/root/ga/scripts/temp/tmp % ls *.tar|while read file
do
echo ; echo "File count in tar file: $file"
tar -tvf $file|wc -l
done
File count in tar file: acqcheat.tar
500
File count in tar file: acqDou.tar
500
File count in tar file: acqDumb.tar
500
File count in tar file: acqfunny.tar
500
>Wed Oct 05|01:20:03|gaurav#[STATION]:/root/ga/scripts/temp/tmp %
Cheers,
Gaurav

Unix `find` command that returns path and whether or not it's a file/directory?

When you do ls -la it returns each path along with info of whether or not it's a file/directory:
$ ls -la
drwxr-xr-x 11 viatropos staff 374 Jan 21 21:24 .
drwxr-xr-x 41 viatropos staff 1394 Feb 2 00:48 ..
-rw-r--r-- 1 viatropos staff 43 Jan 21 21:23 .gitignore
-rw-r--r-- 1 viatropos staff 43 Jan 21 21:23 .npmignore
-rw-r--r-- 1 viatropos staff 647 Jan 21 21:23 README.md
-rw-r--r-- 1 viatropos staff 3069 Feb 5 20:17 index.js
drwxr-xr-x 8 viatropos staff 272 Feb 5 20:06 node_modules
-rw-r--r-- 1 viatropos staff 291 Jan 21 21:24 package.json
drwxr-xr-x 4 viatropos staff 136 Jan 21 21:23 test
Is there a way to do this using the find command (and glob * functionality)? So, finding all paths within node_modules and having it return the path and whether or not it's a file directory? Something like:
$ find node_modules -name 'lib/*'
d node_modules/express/lib/
f node_modules/express/lib/index.js
...
How about find ... -printf '%y %p\n'? (This is probably a GNU find extension, though.)
Try this script, I called it "findfl". The "mtime" clause finds files changed in the last 3 days.
Directories will have "/" appended.
#!/bin/sh
# find files produced recently, matching input pattern
[ $1 ] || { echo "Usage: findfl <file-name-pattern>" ; exit ; }
TOPDIR=/home/usr/fred #the directory you want to search
echo "Searching $TOPDIR"
find . -mtime -3 -name *$1* 2>/dev/null | xargs -n 99 ls -lptr | sed "s! ./! $TOPDIR/!g"

Resources