# File name as standard input



## Bostjan (Jul 25, 2019)

(i’m not proficient, I might use wrong words to ask)





What command can take a file name and provides it as a standard input for another command?





I’ve found some instructions how to do stuff with content of a file or the whole file










						Search results for query: Read file name
					






					forums.freebsd.org
				








How to use file name as an input?





Files, which I have, have the wrong birt time.


st_birthtim







						stat(2)
					






					www.freebsd.org
				








I’m planing to modify the birthtime by fsdb command with btime







						fsdb
					






					www.freebsd.org
				











The file name looks like this (it is actually the birthtime)


2016-12-31 23.59.59.mp4


The time for btime should be in this format YYYYMMDDHHMMSS. Should I just remove the dash “-“, space and two dots or extract each part of the time and date and then put it back together?





You can please also correct my wrong questions.


Thank you.


----------



## SirDice (Jul 25, 2019)

Bostjan said:


> What command can take a file name and provides it as a standard input for another command?


cat(1), echo(1). Depends on how you are handling the input actually. There are also various arguments you could use.



Bostjan said:


> The time for btime should be in this format YYYYMMDDHHMMSS. Should I just remove the dash “-“, space and two dots or extract each part of the time and date and then put it back together?


Look at the format options for date(1). 

Another useful command for your situation is probably basename(1), you can use it to strip off the path and/or the extension. 

I suggest you have a look here: http://www.grymoire.com/Unix/Sh.html


----------



## balanga (Jul 25, 2019)

Maybe you could explain what exactly you are trying to do...


----------



## shepper (Jul 25, 2019)

There are often multiple way to accomplish a task in Unix/Unix-type systems.  If you need to perform the operation on a number of files, sed(1) (stream editor) can replace hyphens and "." with empty spaces and output the edited files.  In addition to the man page, an internet search will find many examples.


----------



## SirDice (Jul 25, 2019)

Bostjan said:


> and provides it as a standard input for another command?


Pretty much every command can have it's STDOUT piped to the STDIN of another. That's one of the cornerstones of UNIX.


----------



## Bostjan (Jul 25, 2019)

balanga I want to change the file's creation date. It has the wrong one. The correct creation date is stated in the file's name. So I want to grab that information (file's name) and use it to change the creation date and time (of course format it properly).
How to take file's name, format the date and use it to change creation date?


----------



## Beastie (Jul 25, 2019)

AFAIK, birthtime can only be set through utimes(2). Or by tinkering with fsdb(8), something I only recommend if you _really_ (note the emphasis) know what you're doing.


----------



## aragats (Jul 25, 2019)

Bostjan , as shepper mentioned above, sed() can do everything you need to form the timestamp, see this simple script:
	
	



```
#!/bin/sh

# for example, if we have a file named:
# myfile-25-07-2019_14:35.dat
# the following command converts its name
# into YYYYMMDDHHMMSS format

if [ "x$1" = "x" ] ; then
    echo Usage $0 '<file>'
fi

TIMESTAMP=`echo $1 | sed 's/[^-]*-\([0-9]*\)-\([0-9]*\)-\([0-9]*\)_\([0-9]*\):\([0-9]*\)\..*/\3\2\1\4\500/'`

# now we can use that value with anything we like:
echo $TIMESTAMP
```
Run it with your filename as argument to see the result.
How to apply it to your file's attributes (using fsdb() or whatever) is another story.


----------



## ralphbsz (Jul 25, 2019)

Bostjan said:


> I want to change the file's creation date. ...
> How to take file's name, format the date and use it to change creation date?


Back up (or actually back down).

In traditional Unix systems, files have three time stamps: the mtime (time the content of the file was last modified), the atime (the time the content of the file was last accessed), and the ctime (the time the metadata of the file was last modified). Some more recent Unix file systems (in particular both ZFS and UFS2 on FreeBSD) also store the birth time of the file; that is an innovation which came from Windows (because the Windows file system has always stored the birth time, it was necessary for Unix file systems to do the same, partially so Unix machines could be used as file servers for Windows networks). Some file systems don't update the atime, or only crudely or sometimes.

This brings up a question: Are you trying to change the ctime or the birthtime of the file?

With the traditional Unix system call utimes(2), it is only possible to set the atime and the mtime. There are very simple but hacky ways to update the ctime to be "right now", namely change the metadata of the file frivolously. For example, you can change the owner or permissions of the file, and immediately change them back. I don't know of a way to change the ctime of a file to an arbitrary value. The reason this is "hacky" is that it is unsafe: If you program crashes between the two updates, you will leave the file with wrong owner or permissions; to do this right you would have to put transactional logging around it, which is a heck of a lot of work. Because the rules for ctime changes are "bizarre" (make perfect sense to a file system implementor, but not really to users), for the most part ctime is unused, and that's a good thing.

It turns out there is a nasty hacky way of changing the birthtime of a file, but AFAIK it only works in one direction: you can make it earlier, not later. Here's how: There is an invariant that the birthtime has to be no later than the mtime. So just change the mtime backwards to before the current birthtime, and the birthtime will be updated with it. Then immediately change the mtime to the real desired value. First, this is again hacky: if you crash in between, you have screwed up. And second it's dangerous, I'm not sure all file systems actually implement this, much less implement this correctly.

In general, updating file metadata (like atime/ctime/mtime/birthtime) is a bad idea. The file system or backup programs may rely on those being set correctly. And they do track the "truth", namely when this particular file was really created/modified/and so on. For example, what happens when you copy a file to another file system? The ctime, mtime and birthtime are guaranteed to change!

Based on all that, here's my advice: Users should not be storing their own metadata in file attributes. That's playing with fire, and hacky. If you have a certain idea of what the creation time of the logical content of the file should be, then store it somewhere other than the ctime or birthtime. There are many ways to do it:

One is storing it in the file itself (if the file format is structured such that you can add information to it).
Another way is to store it in the file name, and use a convention. For example, at home I use my computer(s) to store many paper document, and I have a convention that all such documents have names that start with YYYYMMDD, for example 20190725_electrical_bill.pdf. The date in the file name is the "logical" date of the document, in the case of an electrical bill for example the day the statement date. It is not the date on which I got a paper copy in my mailbox, and even less the day that I scanned the paper document, and copied it to my server.
And if neither the file name nor the content are convenient places for you to store this information, consider using extended attributes. Both UFS and ZFS supported reading and writing extended attributes to files. The only real problem with those is that if you copy the files to other file systems, you have to be careful to only use copy programs that handle extended attributes, and never copy the files to file systems (such as FAT) that don't allow storing extended attributes.


----------



## sean137 (Aug 26, 2019)

ralphbsz said:


> Some more recent Unix file systems (in particular both ZFS and UFS2 on FreeBSD) also store the birth time of the file; that is an innovation which came from Windows



According to Wikipedia, MFS (Macintosh File System) stored creation/birth times since 1984.  So did Apple ProDOS even before that.  FAT supported it only since DOS 7.0 in 1995.  Seems linux got it only with ext4 in 2008.






						Macintosh File System - Wikipedia
					






					en.wikipedia.org
				











						Apple ProDOS - Wikipedia
					






					en.wikipedia.org
				








						File Allocation Table - Wikipedia
					






					en.wikipedia.org
				








						ext4 - Wikipedia
					






					en.wikipedia.org
				





The utimensat man page says "Ideally a new system call will be added that allows the setting of all three times at once."

I searched https://bugs.freebsd.org for such a TODO (to CC myself), but could not find any. Do you know if it exists?


----------

